1
1
const express = require ( 'express' ) ;
2
2
const router = express . Router ( ) ;
3
+ const Block = require ( '../models/Block' ) ;
3
4
4
5
// 获取区块信息
5
6
router . get ( '/block/:blockNumber' , async ( req , res ) => {
6
7
try {
7
- const blockNumber = req . params . blockNumber ;
8
- // TODO: 从数据库获取区块信息
9
- const blockInfo = { } ; // 替换为实际的数据库查询
8
+ const blockNumber = parseInt ( req . params . blockNumber ) ;
9
+ const blockInfo = await Block . findOne ( { number : blockNumber } ) ;
10
+
11
+ if ( ! blockInfo ) {
12
+ return res . status ( 404 ) . json ( {
13
+ success : false ,
14
+ error : '区块未找到'
15
+ } ) ;
16
+ }
17
+
10
18
res . json ( {
11
19
success : true ,
12
20
data : blockInfo
@@ -23,8 +31,16 @@ router.get('/block/:blockNumber', async (req, res) => {
23
31
router . get ( '/transaction/:txHash' , async ( req , res ) => {
24
32
try {
25
33
const txHash = req . params . txHash ;
26
- // TODO: 从数据库获取交易信息
27
- const txInfo = { } ; // 替换为实际的数据库查询
34
+ const block = await Block . findOne ( { 'transactions.hash' : txHash } ) ;
35
+
36
+ if ( ! block ) {
37
+ return res . status ( 404 ) . json ( {
38
+ success : false ,
39
+ error : '交易未找到'
40
+ } ) ;
41
+ }
42
+
43
+ const txInfo = block . transactions . find ( tx => tx . hash === txHash ) ;
28
44
res . json ( {
29
45
success : true ,
30
46
data : txInfo
@@ -40,13 +56,34 @@ router.get('/transaction/:txHash', async (req, res) => {
40
56
// 获取地址的交易历史
41
57
router . get ( '/address/:address/transactions' , async ( req , res ) => {
42
58
try {
43
- const address = req . params . address ;
59
+ const address = req . params . address . toLowerCase ( ) ;
44
60
const page = parseInt ( req . query . page ) || 1 ;
45
61
const limit = parseInt ( req . query . limit ) || 10 ;
62
+ const skip = ( page - 1 ) * limit ;
46
63
47
- // TODO: 从数据库获取地址的交易历史
48
- const transactions = [ ] ; // 替换为实际的数据库查询
49
- const total = 0 ; // 替换为实际的总记录数
64
+ const query = {
65
+ $or : [
66
+ { 'transactions.from' : address } ,
67
+ { 'transactions.to' : address }
68
+ ]
69
+ } ;
70
+
71
+ const [ blocks , total ] = await Promise . all ( [
72
+ Block . find ( query )
73
+ . sort ( { number : - 1 } )
74
+ . skip ( skip )
75
+ . limit ( limit ) ,
76
+ Block . countDocuments ( query )
77
+ ] ) ;
78
+
79
+ const transactions = blocks . reduce ( ( acc , block ) => {
80
+ return acc . concat (
81
+ block . transactions . filter ( tx =>
82
+ tx . from . toLowerCase ( ) === address ||
83
+ ( tx . to && tx . to . toLowerCase ( ) === address )
84
+ )
85
+ ) ;
86
+ } , [ ] ) ;
50
87
51
88
res . json ( {
52
89
success : true ,
@@ -71,8 +108,10 @@ router.get('/address/:address/transactions', async (req, res) => {
71
108
router . get ( '/blocks/latest' , async ( req , res ) => {
72
109
try {
73
110
const limit = parseInt ( req . query . limit ) || 10 ;
74
- // TODO: 从数据库获取最新的区块列表
75
- const blocks = [ ] ; // 替换为实际的数据库查询
111
+ const blocks = await Block . find ( )
112
+ . sort ( { number : - 1 } )
113
+ . limit ( limit )
114
+ . select ( '-transactions' ) ;
76
115
77
116
res . json ( {
78
117
success : true ,
@@ -90,8 +129,14 @@ router.get('/blocks/latest', async (req, res) => {
90
129
router . get ( '/transactions/latest' , async ( req , res ) => {
91
130
try {
92
131
const limit = parseInt ( req . query . limit ) || 10 ;
93
- // TODO: 从数据库获取最新的交易列表
94
- const transactions = [ ] ; // 替换为实际的数据库查询
132
+ const blocks = await Block . find ( )
133
+ . sort ( { number : - 1 } )
134
+ . limit ( Math . ceil ( limit / 2 ) )
135
+ . select ( 'transactions' ) ;
136
+
137
+ const transactions = blocks . reduce ( ( acc , block ) => {
138
+ return acc . concat ( block . transactions ) ;
139
+ } , [ ] ) . slice ( 0 , limit ) ;
95
140
96
141
res . json ( {
97
142
success : true ,
@@ -109,11 +154,52 @@ router.get('/transactions/latest', async (req, res) => {
109
154
router . get ( '/search/:query' , async ( req , res ) => {
110
155
try {
111
156
const query = req . params . query ;
112
- // TODO: 实现搜索逻辑
113
- const result = {
114
- type : '' , // 'block', 'transaction', 'address'
157
+ let result = {
158
+ type : '' ,
115
159
data : null
116
160
} ;
161
+
162
+ // 尝试作为区块号搜索
163
+ if ( / ^ \d + $ / . test ( query ) ) {
164
+ const block = await Block . findOne ( { number : parseInt ( query ) } ) ;
165
+ if ( block ) {
166
+ result = { type : 'block' , data : block } ;
167
+ }
168
+ }
169
+
170
+ // 尝试作为交易哈希搜索
171
+ if ( ! result . data && / ^ 0 x [ a - f A - F 0 - 9 ] { 64 } $ / . test ( query ) ) {
172
+ const block = await Block . findOne ( { 'transactions.hash' : query } ) ;
173
+ if ( block ) {
174
+ const transaction = block . transactions . find ( tx => tx . hash === query ) ;
175
+ if ( transaction ) {
176
+ result = { type : 'transaction' , data : transaction } ;
177
+ }
178
+ }
179
+ }
180
+
181
+ // 尝试作为地址搜索
182
+ if ( ! result . data && / ^ 0 x [ a - f A - F 0 - 9 ] { 40 } $ / . test ( query ) ) {
183
+ const address = query . toLowerCase ( ) ;
184
+ const blocks = await Block . find ( {
185
+ $or : [
186
+ { 'transactions.from' : address } ,
187
+ { 'transactions.to' : address }
188
+ ]
189
+ } ) . limit ( 10 ) ;
190
+
191
+ if ( blocks . length > 0 ) {
192
+ const transactions = blocks . reduce ( ( acc , block ) => {
193
+ return acc . concat (
194
+ block . transactions . filter ( tx =>
195
+ tx . from . toLowerCase ( ) === address ||
196
+ ( tx . to && tx . to . toLowerCase ( ) === address )
197
+ )
198
+ ) ;
199
+ } , [ ] ) ;
200
+ result = { type : 'address' , data : transactions } ;
201
+ }
202
+ }
117
203
118
204
res . json ( {
119
205
success : true ,
@@ -127,4 +213,5 @@ router.get('/search/:query', async (req, res) => {
127
213
}
128
214
} ) ;
129
215
216
+
130
217
module . exports = router ;
0 commit comments