feat: 添加收益模块,包含总收益概览、收益趋势和收益来源,更新相关组件和路由
This commit is contained in:
5
auto-imports.d.ts
vendored
5
auto-imports.d.ts
vendored
@@ -41,7 +41,7 @@ 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 formatAmountWithSplit: typeof import('./src/utils/helper').formatAmountWithSplit
|
||||||
const formatAmountWithUnit: typeof import('./src/utils/helper').formatAmountWithUnit
|
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
|
||||||
@@ -405,7 +405,8 @@ 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 formatAmountWithSplit: UnwrapRef<typeof import('./src/utils/helper')['formatAmountWithSplit']>
|
||||||
|
readonly formatAmountWithUnit: UnwrapRef<typeof import('./src/utils/helper')['formatAmountWithUnit']>
|
||||||
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 getCacheRemainingTime: UnwrapRef<typeof import('./src/composables/useStorageCache')['getCacheRemainingTime']>
|
readonly getCacheRemainingTime: UnwrapRef<typeof import('./src/composables/useStorageCache')['getCacheRemainingTime']>
|
||||||
|
|||||||
6
components.d.ts
vendored
6
components.d.ts
vendored
@@ -39,6 +39,9 @@ declare module 'vue' {
|
|||||||
IonLabel: typeof import('@ionic/vue')['IonLabel']
|
IonLabel: typeof import('@ionic/vue')['IonLabel']
|
||||||
IonList: typeof import('@ionic/vue')['IonList']
|
IonList: typeof import('@ionic/vue')['IonList']
|
||||||
IonListHeader: typeof import('@ionic/vue')['IonListHeader']
|
IonListHeader: typeof import('@ionic/vue')['IonListHeader']
|
||||||
|
IonMenu: typeof import('@ionic/vue')['IonMenu']
|
||||||
|
IonMenuButton: typeof import('@ionic/vue')['IonMenuButton']
|
||||||
|
IonMenuToggle: typeof import('@ionic/vue')['IonMenuToggle']
|
||||||
IonModal: typeof import('@ionic/vue')['IonModal']
|
IonModal: typeof import('@ionic/vue')['IonModal']
|
||||||
IonNote: typeof import('@ionic/vue')['IonNote']
|
IonNote: typeof import('@ionic/vue')['IonNote']
|
||||||
IonPage: typeof import('@ionic/vue')['IonPage']
|
IonPage: typeof import('@ionic/vue')['IonPage']
|
||||||
@@ -97,6 +100,9 @@ declare global {
|
|||||||
const IonLabel: typeof import('@ionic/vue')['IonLabel']
|
const IonLabel: typeof import('@ionic/vue')['IonLabel']
|
||||||
const IonList: typeof import('@ionic/vue')['IonList']
|
const IonList: typeof import('@ionic/vue')['IonList']
|
||||||
const IonListHeader: typeof import('@ionic/vue')['IonListHeader']
|
const IonListHeader: typeof import('@ionic/vue')['IonListHeader']
|
||||||
|
const IonMenu: typeof import('@ionic/vue')['IonMenu']
|
||||||
|
const IonMenuButton: typeof import('@ionic/vue')['IonMenuButton']
|
||||||
|
const IonMenuToggle: typeof import('@ionic/vue')['IonMenuToggle']
|
||||||
const IonModal: typeof import('@ionic/vue')['IonModal']
|
const IonModal: typeof import('@ionic/vue')['IonModal']
|
||||||
const IonNote: typeof import('@ionic/vue')['IonNote']
|
const IonNote: typeof import('@ionic/vue')['IonNote']
|
||||||
const IonPage: typeof import('@ionic/vue')['IonPage']
|
const IonPage: typeof import('@ionic/vue')['IonPage']
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
"@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.27:9527/api/riwa-api-types-0.0.64.tgz",
|
"@riwa/api-types": "http://192.168.1.27:9527/api/riwa-api-types-0.0.67.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",
|
||||||
|
|||||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -57,8 +57,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.27:9527/api/riwa-api-types-0.0.64.tgz
|
specifier: http://192.168.1.27:9527/api/riwa-api-types-0.0.67.tgz
|
||||||
version: http://192.168.1.27:9527/api/riwa-api-types-0.0.64.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.27:9527/api/riwa-api-types-0.0.67.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))
|
||||||
@@ -1401,9 +1401,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.27:9527/api/riwa-api-types-0.0.64.tgz':
|
'@riwa/api-types@http://192.168.1.27:9527/api/riwa-api-types-0.0.67.tgz':
|
||||||
resolution: {tarball: http://192.168.1.27:9527/api/riwa-api-types-0.0.64.tgz}
|
resolution: {tarball: http://192.168.1.27:9527/api/riwa-api-types-0.0.67.tgz}
|
||||||
version: 0.0.64
|
version: 0.0.67
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@elysiajs/eden': ^1.4.5
|
'@elysiajs/eden': ^1.4.5
|
||||||
|
|
||||||
@@ -6644,7 +6644,7 @@ snapshots:
|
|||||||
|
|
||||||
'@pkgr/core@0.2.9': {}
|
'@pkgr/core@0.2.9': {}
|
||||||
|
|
||||||
'@riwa/api-types@http://192.168.1.27:9527/api/riwa-api-types-0.0.64.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.27:9527/api/riwa-api-types-0.0.67.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))
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import type { Awaitable } from "@vueuse/core";
|
import type { Awaitable } from "@vueuse/core";
|
||||||
import type { ChartOptions, DeepPartial, IChartApi, ISeriesApi, LayoutOptions, OhlcData, SeriesType } from "lightweight-charts";
|
import type { ChartOptions, DeepPartial, IChartApi, ISeriesApi, LayoutOptions, OhlcData, SeriesDataItemTypeMap, SeriesType } from "lightweight-charts";
|
||||||
import type { ThemeMode } from "./useTheme";
|
import type { ThemeMode } from "./useTheme";
|
||||||
import { AreaSeries, BarSeries, BaselineSeries, CandlestickSeries, ColorType, createChart, HistogramSeries, LineSeries } from "lightweight-charts";
|
import { AreaSeries, BarSeries, BaselineSeries, CandlestickSeries, ColorType, createChart, HistogramSeries, LineSeries } from "lightweight-charts";
|
||||||
import { mergeWith } from "lodash-es";
|
import { mergeWith } from "lodash-es";
|
||||||
|
|
||||||
export type Series = "Area" | "Bar" | "Baseline" | "Candlestick" | "Histogram" | "Line";
|
export type Series = "Area" | "Bar" | "Baseline" | "Candlestick" | "Histogram" | "Line";
|
||||||
|
|
||||||
export type TData = OhlcData;
|
export type TData = SeriesDataItemTypeMap[SeriesType];
|
||||||
|
|
||||||
export type WeightChartOptions = DeepPartial<ChartOptions>;
|
export type WeightChartOptions = DeepPartial<ChartOptions>;
|
||||||
|
|
||||||
|
|||||||
@@ -241,6 +241,44 @@
|
|||||||
"revenueDetails": "Revenue Details"
|
"revenueDetails": "Revenue Details"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"income": {
|
||||||
|
"title": "Total Revenue",
|
||||||
|
"overview": {
|
||||||
|
"totalRevenue": "Total Revenue",
|
||||||
|
"yesterdayRevenue": "Yesterday's Revenue",
|
||||||
|
"monthRevenue": "This Month",
|
||||||
|
"pendingRevenue": "Pending Revenue"
|
||||||
|
},
|
||||||
|
"trend": {
|
||||||
|
"title": "Revenue Trend",
|
||||||
|
"last7Days": "Last 7 Days",
|
||||||
|
"last30Days": "Last 30 Days",
|
||||||
|
"last90Days": "Last 90 Days"
|
||||||
|
},
|
||||||
|
"sources": {
|
||||||
|
"title": "Revenue Sources",
|
||||||
|
"dividend": "Dividend",
|
||||||
|
"appreciation": "Appreciation",
|
||||||
|
"trade": "Trading"
|
||||||
|
},
|
||||||
|
"records": {
|
||||||
|
"title": "Revenue Records",
|
||||||
|
"all": "All",
|
||||||
|
"recent": "Recent Records",
|
||||||
|
"viewAll": "View All",
|
||||||
|
"assetName": "Asset Name",
|
||||||
|
"type": "Type",
|
||||||
|
"amount": "Amount",
|
||||||
|
"date": "Date",
|
||||||
|
"status": "Status",
|
||||||
|
"noData": "No revenue records"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"completed": "Completed",
|
||||||
|
"pending": "Pending",
|
||||||
|
"processing": "Processing"
|
||||||
|
}
|
||||||
|
},
|
||||||
"myIssues": {
|
"myIssues": {
|
||||||
"title": "My Issuance Applications",
|
"title": "My Issuance Applications",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
@@ -317,7 +355,10 @@
|
|||||||
"common": {
|
"common": {
|
||||||
"failedSendCode": "Failed to send verification code",
|
"failedSendCode": "Failed to send verification code",
|
||||||
"uploadFile": "Upload File",
|
"uploadFile": "Upload File",
|
||||||
"files": "files"
|
"files": "files",
|
||||||
|
"today": "Today",
|
||||||
|
"yesterday": "Yesterday",
|
||||||
|
"items": "items"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": {
|
"login": {
|
||||||
|
|||||||
@@ -247,6 +247,44 @@
|
|||||||
"revenueDetails": "收益明细"
|
"revenueDetails": "收益明细"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"income": {
|
||||||
|
"title": "总收益",
|
||||||
|
"overview": {
|
||||||
|
"totalRevenue": "累计总收益",
|
||||||
|
"yesterdayRevenue": "昨日收益",
|
||||||
|
"monthRevenue": "本月收益",
|
||||||
|
"pendingRevenue": "待确认收益"
|
||||||
|
},
|
||||||
|
"trend": {
|
||||||
|
"title": "收益趋势",
|
||||||
|
"last7Days": "最近7天",
|
||||||
|
"last30Days": "最近30天",
|
||||||
|
"last90Days": "最近90天"
|
||||||
|
},
|
||||||
|
"sources": {
|
||||||
|
"title": "收益来源",
|
||||||
|
"dividend": "分红收益",
|
||||||
|
"appreciation": "资产增值",
|
||||||
|
"trade": "交易收益"
|
||||||
|
},
|
||||||
|
"records": {
|
||||||
|
"title": "收益明细",
|
||||||
|
"all": "全部",
|
||||||
|
"recent": "最近记录",
|
||||||
|
"viewAll": "查看全部",
|
||||||
|
"assetName": "资产名称",
|
||||||
|
"type": "类型",
|
||||||
|
"amount": "金额",
|
||||||
|
"date": "日期",
|
||||||
|
"status": "状态",
|
||||||
|
"noData": "暂无收益记录"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"completed": "已完成",
|
||||||
|
"pending": "待确认",
|
||||||
|
"processing": "处理中"
|
||||||
|
}
|
||||||
|
},
|
||||||
"myIssues": {
|
"myIssues": {
|
||||||
"title": "我的发行申请",
|
"title": "我的发行申请",
|
||||||
"search": "搜索",
|
"search": "搜索",
|
||||||
@@ -323,7 +361,10 @@
|
|||||||
"common": {
|
"common": {
|
||||||
"failedSendCode": "发送验证码失败",
|
"failedSendCode": "发送验证码失败",
|
||||||
"uploadFile": "上传文件",
|
"uploadFile": "上传文件",
|
||||||
"files": "个文件"
|
"files": "个文件",
|
||||||
|
"today": "今天",
|
||||||
|
"yesterday": "昨天",
|
||||||
|
"items": "项"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": {
|
"login": {
|
||||||
|
|||||||
129
src/mocks/data/income.ts
Normal file
129
src/mocks/data/income.ts
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
import { useMocks } from "../index";
|
||||||
|
|
||||||
|
const mocks = useMocks();
|
||||||
|
|
||||||
|
// 总收益 Mock 数据
|
||||||
|
mocks.register("income/total", () => {
|
||||||
|
return {
|
||||||
|
// 总收益概览
|
||||||
|
overview: {
|
||||||
|
totalRevenue: 125680.50, // 累计总收益
|
||||||
|
yesterdayRevenue: 1256.80, // 昨日收益
|
||||||
|
monthRevenue: 38450.20, // 本月收益
|
||||||
|
pendingRevenue: 5420.30, // 待确认收益
|
||||||
|
currency: "USD",
|
||||||
|
},
|
||||||
|
// 收益趋势数据(最近7天)
|
||||||
|
trend: [
|
||||||
|
{ date: "2025-12-21", revenue: 1100.50 },
|
||||||
|
{ date: "2025-12-22", revenue: 1300.80 },
|
||||||
|
{ date: "2025-12-23", revenue: 1450.20 },
|
||||||
|
{ date: "2025-12-24", revenue: 1200.60 },
|
||||||
|
{ date: "2025-12-25", revenue: 1350.90 },
|
||||||
|
{ date: "2025-12-26", revenue: 1380.40 },
|
||||||
|
{ date: "2025-12-27", revenue: 1256.80 },
|
||||||
|
],
|
||||||
|
// 收益来源分布
|
||||||
|
sources: [
|
||||||
|
{
|
||||||
|
type: "dividend", // 分红收益
|
||||||
|
name: "分红收益",
|
||||||
|
amount: 85420.30,
|
||||||
|
percentage: 67.96,
|
||||||
|
count: 125,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "appreciation", // 资产增值
|
||||||
|
name: "资产增值",
|
||||||
|
amount: 32150.20,
|
||||||
|
percentage: 25.59,
|
||||||
|
count: 45,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "trade", // 交易收益
|
||||||
|
name: "交易收益",
|
||||||
|
amount: 8110.00,
|
||||||
|
percentage: 6.45,
|
||||||
|
count: 89,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 最近收益明细
|
||||||
|
recentRecords: [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
type: "dividend",
|
||||||
|
typeName: "分红收益",
|
||||||
|
assetName: "纽约曼哈顿中心公寓",
|
||||||
|
assetCode: "NYC-001",
|
||||||
|
amount: 520.50,
|
||||||
|
currency: "USD",
|
||||||
|
date: "2025-12-27 10:30:00",
|
||||||
|
status: "completed", // completed, pending, processing
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
type: "appreciation",
|
||||||
|
typeName: "资产增值",
|
||||||
|
assetName: "旧金山商业地产",
|
||||||
|
assetCode: "SF-002",
|
||||||
|
amount: 320.80,
|
||||||
|
currency: "USD",
|
||||||
|
date: "2025-12-27 09:15:00",
|
||||||
|
status: "completed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3",
|
||||||
|
type: "trade",
|
||||||
|
typeName: "交易收益",
|
||||||
|
assetName: "洛杉矶住宅楼",
|
||||||
|
assetCode: "LA-003",
|
||||||
|
amount: 215.50,
|
||||||
|
currency: "USD",
|
||||||
|
date: "2025-12-26 16:45:00",
|
||||||
|
status: "completed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "4",
|
||||||
|
type: "dividend",
|
||||||
|
typeName: "分红收益",
|
||||||
|
assetName: "迈阿密海景别墅",
|
||||||
|
assetCode: "MIA-004",
|
||||||
|
amount: 680.20,
|
||||||
|
currency: "USD",
|
||||||
|
date: "2025-12-26 14:20:00",
|
||||||
|
status: "pending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "5",
|
||||||
|
type: "appreciation",
|
||||||
|
typeName: "资产增值",
|
||||||
|
assetName: "芝加哥写字楼",
|
||||||
|
assetCode: "CHI-005",
|
||||||
|
amount: 450.60,
|
||||||
|
currency: "USD",
|
||||||
|
date: "2025-12-25 11:30:00",
|
||||||
|
status: "completed",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// 收益明细列表(支持筛选)
|
||||||
|
mocks.register("income/records", () => {
|
||||||
|
return {
|
||||||
|
list: Array.from({ length: 20 }, (_, index) => ({
|
||||||
|
id: String(index + 1),
|
||||||
|
type: ["dividend", "appreciation", "trade"][index % 3],
|
||||||
|
typeName: ["分红收益", "资产增值", "交易收益"][index % 3],
|
||||||
|
assetName: `资产名称 ${index + 1}`,
|
||||||
|
assetCode: `ASSET-${String(index + 1).padStart(3, "0")}`,
|
||||||
|
amount: (Math.random() * 1000 + 100).toFixed(2),
|
||||||
|
currency: "USD",
|
||||||
|
date: new Date(Date.now() - index * 86400000).toISOString(),
|
||||||
|
status: ["completed", "pending", "processing"][index % 3],
|
||||||
|
})),
|
||||||
|
total: 100,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -1 +1,2 @@
|
|||||||
import "./notify";
|
import "./notify";
|
||||||
|
import "./income";
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
component: () => import("@/views/withdraw/index.vue"),
|
component: () => import("@/views/withdraw/index.vue"),
|
||||||
meta: { requiresAuth: true },
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/income/total",
|
||||||
|
component: () => import("@/views/income/total/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/wallet/bill",
|
path: "/wallet/bill",
|
||||||
component: () => import("@/views/wallet/bill.vue"),
|
component: () => import("@/views/wallet/bill.vue"),
|
||||||
@@ -135,12 +140,12 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
component: () => import("@/views/trade-settings/my-subscribe/index.vue"),
|
component: () => import("@/views/trade-settings/my-subscribe/index.vue"),
|
||||||
meta: { requiresAuth: true },
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// path: ":id",
|
path: ":id",
|
||||||
// props: true,
|
props: true,
|
||||||
// component: () => import("@/views/trade-settings/my-subscribe/detail.vue"),
|
component: () => import("@/views/trade-settings/my-subscribe/detail.vue"),
|
||||||
// meta: { requiresAuth: true },
|
meta: { requiresAuth: true },
|
||||||
// },
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ html.ion-palette-light {
|
|||||||
--ion-color-tertiary-tint: #757575;
|
--ion-color-tertiary-tint: #757575;
|
||||||
|
|
||||||
--ion-color-success: #2c810e;
|
--ion-color-success: #2c810e;
|
||||||
--ion-color-success-rgb: 44,129,14;
|
--ion-color-success-rgb: 44, 129, 14;
|
||||||
--ion-color-success-contrast: #ffffff;
|
--ion-color-success-contrast: #ffffff;
|
||||||
--ion-color-success-contrast-rgb: 255,255,255;
|
--ion-color-success-contrast-rgb: 255, 255, 255;
|
||||||
--ion-color-success-shade: #27720c;
|
--ion-color-success-shade: #27720c;
|
||||||
--ion-color-success-tint: #418e26;
|
--ion-color-success-tint: #418e26;
|
||||||
|
|
||||||
--ion-color-warning: #ffc409;
|
--ion-color-warning: #ffc409;
|
||||||
--ion-color-warning-rgb: 255, 196, 9;
|
--ion-color-warning-rgb: 255, 196, 9;
|
||||||
@@ -143,11 +143,11 @@ html.ion-palette-dark {
|
|||||||
--ion-color-tertiary-tint: #dadada;
|
--ion-color-tertiary-tint: #dadada;
|
||||||
|
|
||||||
--ion-color-success: #2c810e;
|
--ion-color-success: #2c810e;
|
||||||
--ion-color-success-rgb: 44,129,14;
|
--ion-color-success-rgb: 44, 129, 14;
|
||||||
--ion-color-success-contrast: #ffffff;
|
--ion-color-success-contrast: #ffffff;
|
||||||
--ion-color-success-contrast-rgb: 255,255,255;
|
--ion-color-success-contrast-rgb: 255, 255, 255;
|
||||||
--ion-color-success-shade: #27720c;
|
--ion-color-success-shade: #27720c;
|
||||||
--ion-color-success-tint: #418e26;
|
--ion-color-success-tint: #418e26;
|
||||||
|
|
||||||
--ion-color-warning: #ffc409;
|
--ion-color-warning: #ffc409;
|
||||||
--ion-color-warning-rgb: 255, 196, 9;
|
--ion-color-warning-rgb: 255, 196, 9;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function timeToLocal(originalTime: number) {
|
|||||||
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 {
|
export function formatAmountWithUnit(amount: MaybeRefOrGetter<number | string | null | undefined>): string {
|
||||||
const value = toValue(amount);
|
const value = toValue(amount);
|
||||||
if (Number.isNaN(Number(value))) {
|
if (Number.isNaN(Number(value))) {
|
||||||
return "0";
|
return "0";
|
||||||
@@ -24,21 +24,37 @@ export function formatAmount(amount: MaybeRefOrGetter<number | string | null | u
|
|||||||
const num = Number(value);
|
const num = Number(value);
|
||||||
|
|
||||||
// 不超过1万,原样显示
|
// 不超过1万,原样显示
|
||||||
if (num < 10000) {
|
if (num < 1e4) {
|
||||||
return String(num);
|
return String(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1亿以上,显示为xx亿
|
// 1亿以上,显示为xx亿
|
||||||
if (num >= 100000000) {
|
if (num >= 1e8) {
|
||||||
const yi = (num / 100000000).toFixed(1);
|
const yi = (num / 1e8).toFixed(1);
|
||||||
return yi.endsWith(".0") ? `${Number.parseInt(yi)}亿` : `${yi}亿`;
|
return yi.endsWith(".0") ? `${Number.parseInt(yi)}亿` : `${yi}亿`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1万到1亿,显示为xx万
|
// 1万到1亿,显示为xx万
|
||||||
if (num >= 10000) {
|
if (num >= 1e4) {
|
||||||
const wan = (num / 10000).toFixed(1);
|
const wan = (num / 1e4).toFixed(1);
|
||||||
return wan.endsWith(".0") ? `${Number.parseInt(wan)}万` : `${wan}万`;
|
return wan.endsWith(".0") ? `${Number.parseInt(wan)}万` : `${wan}万`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return String(num);
|
return String(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function formatAmountWithSplit(amount: MaybeRefOrGetter<number | string | null | undefined>): string {
|
||||||
|
const value = toValue(amount);
|
||||||
|
if (Number.isNaN(Number(value))) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
const num = Number(value);
|
||||||
|
|
||||||
|
return Intl.NumberFormat("en-US", {
|
||||||
|
style: "currency",
|
||||||
|
currency: "USD",
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
}).format(num);
|
||||||
|
}
|
||||||
|
|||||||
41
src/views/income/total/components/overview.vue
Normal file
41
src/views/income/total/components/overview.vue
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<script lang='ts' setup>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="bg-text-900 rounded-xl p-7">
|
||||||
|
<div>
|
||||||
|
<div class="text-sm mb-2">
|
||||||
|
累计总收益
|
||||||
|
</div>
|
||||||
|
<div class="text-4xl font-bold">
|
||||||
|
{{ formatAmountWithSplit(190421321) }}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2 text-xs mt-1">
|
||||||
|
<div>昨日收益</div>
|
||||||
|
<div>+{{ formatAmountWithSplit(864314) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="h-px bg-text-800 my-5" />
|
||||||
|
<div class="flex justify-around">
|
||||||
|
<div class="flex-col-center">
|
||||||
|
<div class="text-base font-bold">
|
||||||
|
{{ formatAmountWithSplit(42523) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs">
|
||||||
|
本月收益
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="h-auto w-px bg-text-800" />
|
||||||
|
<div class="flex-col-center">
|
||||||
|
<div class="text-base font-bold">
|
||||||
|
{{ formatAmountWithSplit(12345) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs">
|
||||||
|
待确认收益
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='css' scoped></style>
|
||||||
59
src/views/income/total/components/trend.vue
Normal file
59
src/views/income/total/components/trend.vue
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<script lang='ts' setup>
|
||||||
|
const tradingViewInst = useTemplateRef<HTMLDivElement>("tradingViewInst");
|
||||||
|
|
||||||
|
useTradingView(tradingViewInst, {
|
||||||
|
type: "Area",
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
time: "2023-01-01",
|
||||||
|
value: 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: "2023-02-01",
|
||||||
|
value: 1200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: "2023-03-01",
|
||||||
|
value: 900,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: "2023-04-01",
|
||||||
|
value: 1400,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: "2023-05-01",
|
||||||
|
value: 1300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: "2023-06-01",
|
||||||
|
value: 1500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: "2023-07-01",
|
||||||
|
value: 1700,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: "2023-08-01",
|
||||||
|
value: 1600,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
weightChartOptions: {
|
||||||
|
height: 150,
|
||||||
|
rightPriceScale: {
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
leftPriceScale: {
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h4>收益趋势</h4>
|
||||||
|
<div ref="tradingViewInst" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='css' scoped></style>
|
||||||
53
src/views/income/total/index.vue
Normal file
53
src/views/income/total/index.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<script lang='ts' setup>
|
||||||
|
import type { RefresherCustomEvent } from "@ionic/vue";
|
||||||
|
import { mockClient } from "@/api";
|
||||||
|
import Overview from "./components/overview.vue";
|
||||||
|
import Trend from "./components/trend.vue";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { vibrate } = useHaptics();
|
||||||
|
|
||||||
|
// 收益数据
|
||||||
|
const loading = ref(true);
|
||||||
|
const { data } = await mockClient("income/total");
|
||||||
|
|
||||||
|
async function loadIncomeData() {
|
||||||
|
loading.value = true;
|
||||||
|
useTimeoutFn(() => {
|
||||||
|
loading.value = false;
|
||||||
|
}, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleRefresh(event: RefresherCustomEvent) {
|
||||||
|
vibrate();
|
||||||
|
useTimeoutFn(() => {
|
||||||
|
event.target.complete();
|
||||||
|
}, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadIncomeData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ion-page>
|
||||||
|
<ion-header class="ion-no-border">
|
||||||
|
<ion-toolbar class="ui-toolbar">
|
||||||
|
<ion-back-button slot="start" />
|
||||||
|
<ion-title>{{ t("income.title") }}</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content :fullscreen="true" class="ion-padding">
|
||||||
|
<ion-refresher slot="fixed" @ion-refresh="handleRefresh($event)">
|
||||||
|
<ion-refresher-content />
|
||||||
|
</ion-refresher>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Overview />
|
||||||
|
<Trend />
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
|
</ion-page>
|
||||||
|
</template>
|
||||||
@@ -33,7 +33,7 @@ const { t } = useI18n();
|
|||||||
<div class="label">
|
<div class="label">
|
||||||
{{ t('market.tradeRwa.fields.valuation') }}
|
{{ t('market.tradeRwa.fields.valuation') }}
|
||||||
</div>
|
</div>
|
||||||
<div>${{ formatAmount(data?.product.estimatedValue) }}</div>
|
<div>${{ formatAmountWithUnit(data?.product.estimatedValue) }}</div>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
<ion-row>
|
<ion-row>
|
||||||
@@ -41,7 +41,7 @@ const { t } = useI18n();
|
|||||||
<div class="label">
|
<div class="label">
|
||||||
{{ t('market.tradeRwa.fields.unitPrice') }}
|
{{ t('market.tradeRwa.fields.unitPrice') }}
|
||||||
</div>
|
</div>
|
||||||
<div>${{ formatAmount(data?.unitPrice) }}</div>
|
<div>${{ formatAmountWithUnit(data?.unitPrice) }}</div>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<div class="label">
|
<div class="label">
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ onUpdated(() => {
|
|||||||
</p>
|
</p>
|
||||||
<ion-button
|
<ion-button
|
||||||
expand="block"
|
expand="block"
|
||||||
color="success"
|
fill="outline"
|
||||||
@click="handleAddCard"
|
@click="handleAddCard"
|
||||||
>
|
>
|
||||||
<ion-icon slot="start" :icon="addOutline" />
|
<ion-icon slot="start" :icon="addOutline" />
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const { t } = useI18n();
|
|||||||
<div class="label">
|
<div class="label">
|
||||||
{{ t('market.tradeRwa.fields.valuation') }}
|
{{ t('market.tradeRwa.fields.valuation') }}
|
||||||
</div>
|
</div>
|
||||||
<div>${{ formatAmount(data?.estimatedValue) }}</div>
|
<div>${{ formatAmountWithUnit(data?.estimatedValue) }}</div>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
</ion-grid>
|
</ion-grid>
|
||||||
|
|||||||
@@ -28,16 +28,13 @@ async function handleSubscribe(val: number) {
|
|||||||
await toast.present();
|
await toast.present();
|
||||||
model.value?.$el.dismiss();
|
model.value?.$el.dismiss();
|
||||||
}
|
}
|
||||||
function gotoEdit() {
|
|
||||||
router.push({ name: "trade-rwa-edit" });
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ion-page>
|
<ion-page>
|
||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar class="ui-toolbar">
|
<ion-toolbar class="ui-toolbar">
|
||||||
<ion-back-button slot="start" text="" />
|
<ion-back-button slot="start" />
|
||||||
<ion-title>
|
<ion-title>
|
||||||
{{ data?.edition.product.code }}
|
{{ data?.edition.product.code }}
|
||||||
</ion-title>
|
</ion-title>
|
||||||
@@ -53,7 +50,7 @@ function gotoEdit() {
|
|||||||
{{ data?.edition.product.name }}
|
{{ data?.edition.product.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-gray-500 font-semibold">
|
<div class="text-xs text-gray-500 font-semibold">
|
||||||
{{ data?.edition.product.categoryId }}
|
{{ data?.edition.product.code }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,13 +3,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ion-page>
|
<ion-page>
|
||||||
<ion-header>
|
<ion-router-outlet />
|
||||||
<ion-toolbar class="ui-toolbar">
|
|
||||||
<ion-back-button slot="start" />
|
|
||||||
<ion-title>我的申购</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
</ion-header>
|
|
||||||
<router-view />
|
|
||||||
</ion-page>
|
</ion-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
import { calendarOutline, listOutline, timeOutline, walletOutline } from "ionicons/icons";
|
import { calendarOutline, listOutline, timeOutline, walletOutline } from "ionicons/icons";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const router = useRouter();
|
||||||
|
const { vibrate } = useHaptics();
|
||||||
|
|
||||||
|
function navigateToTotal() {
|
||||||
|
vibrate();
|
||||||
|
router.push("/income/total");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -10,26 +17,29 @@ const { t } = useI18n();
|
|||||||
{{ t("asset.revenue.myRevenue") }}
|
{{ t("asset.revenue.myRevenue") }}
|
||||||
</ion-label>
|
</ion-label>
|
||||||
<div class="grid grid-cols-4 mt-5">
|
<div class="grid grid-cols-4 mt-5">
|
||||||
<div class="col-span-1 flex-col-center gap-2">
|
<div
|
||||||
<ion-icon :icon="walletOutline" />
|
class="col-span-1 flex flex-col items-center gap-2 cursor-pointer transition-opacity active:opacity-70"
|
||||||
|
@click="navigateToTotal"
|
||||||
|
>
|
||||||
|
<ion-icon :icon="walletOutline" class="text-2xl text-primary" />
|
||||||
<div class="text-xs">
|
<div class="text-xs">
|
||||||
{{ t("asset.revenue.totalRevenue") }}
|
{{ t("asset.revenue.totalRevenue") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-1 flex-col-center gap-2">
|
<div class="col-span-1 flex flex-col items-center gap-2 cursor-pointer transition-opacity active:opacity-70">
|
||||||
<ion-icon :icon="calendarOutline" />
|
<ion-icon :icon="calendarOutline" class="text-2xl text-primary" />
|
||||||
<div class="text-xs">
|
<div class="text-xs">
|
||||||
{{ t("asset.revenue.monthlyRevenue") }}
|
{{ t("asset.revenue.monthlyRevenue") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-1 flex-col-center gap-2">
|
<div class="col-span-1 flex flex-col items-center gap-2 cursor-pointer transition-opacity active:opacity-70">
|
||||||
<ion-icon :icon="timeOutline" />
|
<ion-icon :icon="timeOutline" class="text-2xl text-primary" />
|
||||||
<div class="text-xs">
|
<div class="text-xs">
|
||||||
{{ t("asset.revenue.pendingRevenue") }}
|
{{ t("asset.revenue.pendingRevenue") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-1 flex-col-center gap-2">
|
<div class="col-span-1 flex flex-col items-center gap-2 cursor-pointer transition-opacity active:opacity-70">
|
||||||
<ion-icon :icon="listOutline" />
|
<ion-icon :icon="listOutline" class="text-2xl text-primary" />
|
||||||
<div class="text-xs">
|
<div class="text-xs">
|
||||||
{{ t("asset.revenue.revenueDetails") }}
|
{{ t("asset.revenue.revenueDetails") }}
|
||||||
</div>
|
</div>
|
||||||
@@ -37,10 +47,3 @@ const { t } = useI18n();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang='css' scoped>
|
|
||||||
ion-icon {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
color: var(--ion-color-primary);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ async function handleScan() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<IonPage>
|
<ion-page>
|
||||||
<ion-header class="ion-no-border">
|
<ion-header class="ion-no-border">
|
||||||
<ion-toolbar class="ui-toolbar">
|
<ion-toolbar class="ui-toolbar">
|
||||||
<div slot="end">
|
<div slot="end">
|
||||||
@@ -55,7 +55,7 @@ async function handleScan() {
|
|||||||
</div>
|
</div>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<IonContent :fullscreen="true" class="ion-padding">
|
<ion-content :fullscreen="true" class="ion-padding">
|
||||||
<ion-refresher slot="fixed" @ion-refresh="handleRefresh($event)">
|
<ion-refresher slot="fixed" @ion-refresh="handleRefresh($event)">
|
||||||
<ion-refresher-content />
|
<ion-refresher-content />
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
@@ -68,8 +68,8 @@ async function handleScan() {
|
|||||||
<MyRevenue />
|
<MyRevenue />
|
||||||
<TradeSettings />
|
<TradeSettings />
|
||||||
</div>
|
</div>
|
||||||
</IonContent>
|
</ion-content>
|
||||||
</IonPage>
|
</ion-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
3
vault.md
3
vault.md
@@ -1,10 +1,9 @@
|
|||||||
open float Y 开盘价 每一个纬度(例如天纬度,就是一天的第一笔成交价格)的第一笔成交价格
|
open float Y 开盘价 每一个纬度(例如天纬度,就是一天的第一笔成交价格)的第一笔成交价格
|
||||||
high float Y 最高价
|
high float Y 最高价
|
||||||
low float Y 最低价
|
low float Y 最低价
|
||||||
close float Y 收盘价
|
close float Y 收盘价
|
||||||
settle float Y 结算价 每一个纬度(某一个时间段之内的金额总和 / 交易量)
|
settle float Y 结算价 每一个纬度(某一个时间段之内的金额总和 / 交易量)
|
||||||
|
|
||||||
|
|
||||||
接口
|
接口
|
||||||
代币化分类接口
|
代币化分类接口
|
||||||
代币化列表接口
|
代币化列表接口
|
||||||
|
|||||||
Reference in New Issue
Block a user