f6a1a6c9 by astaxie

Merge pull request #773 from lei-cao/develop

Added data table admin ui
2 parents 771179a3 38ee4370
...@@ -142,121 +142,116 @@ func listConf(rw http.ResponseWriter, r *http.Request) { ...@@ -142,121 +142,116 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
142 tmpl.Execute(rw, data) 142 tmpl.Execute(rw, data)
143 143
144 case "router": 144 case "router":
145 resultList := new([][]string) 145 content := make(map[string]interface{})
146 146
147 var result = []string{ 147 var fields = []string{
148 fmt.Sprintf("header"),
149 fmt.Sprintf("Router Pattern"), 148 fmt.Sprintf("Router Pattern"),
150 fmt.Sprintf("Methods"), 149 fmt.Sprintf("Methods"),
151 fmt.Sprintf("Controller"), 150 fmt.Sprintf("Controller"),
152 } 151 }
153 *resultList = append(*resultList, result) 152 content["Fields"] = fields
154 153
154 methods := []string{}
155 methodsData := make(map[string]interface{})
155 for method, t := range BeeApp.Handlers.routers { 156 for method, t := range BeeApp.Handlers.routers {
156 var result = []string{ 157
157 fmt.Sprintf("success"), 158 resultList := new([][]string)
158 fmt.Sprintf("Method: %s", method),
159 fmt.Sprintf(""),
160 fmt.Sprintf(""),
161 }
162 *resultList = append(*resultList, result)
163 159
164 printTree(resultList, t) 160 printTree(resultList, t)
161
162 methods = append(methods, method)
163 methodsData[method] = resultList
165 } 164 }
166 data["Content"] = resultList 165
166 content["Data"] = methodsData
167 content["Methods"] = methods
168 data["Content"] = content
167 data["Title"] = "Routers" 169 data["Title"] = "Routers"
170
168 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) 171 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
169 tmpl = template.Must(tmpl.Parse(routerAndFilterTpl)) 172 tmpl = template.Must(tmpl.Parse(routerAndFilterTpl))
170 tmpl = template.Must(tmpl.Parse(defaultScriptsTpl)) 173 tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
171 tmpl.Execute(rw, data) 174 tmpl.Execute(rw, data)
172 case "filter": 175 case "filter":
173 resultList := new([][]string) 176 content := make(map[string]interface{})
174 177
175 var result = []string{ 178 var fields = []string{
176 fmt.Sprintf("header"),
177 fmt.Sprintf("Router Pattern"), 179 fmt.Sprintf("Router Pattern"),
178 fmt.Sprintf("Filter Function"), 180 fmt.Sprintf("Filter Function"),
179 } 181 }
180 *resultList = append(*resultList, result) 182 content["Fields"] = fields
183
184 filterTypes := []string{}
185 filterTypeData := make(map[string]interface{})
181 186
182 if BeeApp.Handlers.enableFilter { 187 if BeeApp.Handlers.enableFilter {
183 var result = []string{ 188 var filterType string
184 fmt.Sprintf("success"),
185 fmt.Sprintf("Before Router"),
186 fmt.Sprintf(""),
187 }
188 *resultList = append(*resultList, result)
189 189
190 if bf, ok := BeeApp.Handlers.filters[BeforeRouter]; ok { 190 if bf, ok := BeeApp.Handlers.filters[BeforeRouter]; ok {
191 filterType = "Before Router"
192 filterTypes = append(filterTypes, filterType)
193 resultList := new([][]string)
191 for _, f := range bf { 194 for _, f := range bf {
192 195
193 var result = []string{ 196 var result = []string{
194 fmt.Sprintf(""),
195 fmt.Sprintf("%s", f.pattern), 197 fmt.Sprintf("%s", f.pattern),
196 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), 198 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
197 } 199 }
198 *resultList = append(*resultList, result) 200 *resultList = append(*resultList, result)
199
200 }
201 } 201 }
202 result = []string{ 202 filterTypeData[filterType] = resultList
203 fmt.Sprintf("success"),
204 fmt.Sprintf("Before Exec"),
205 fmt.Sprintf(""),
206 } 203 }
207 *resultList = append(*resultList, result) 204
208 if bf, ok := BeeApp.Handlers.filters[BeforeExec]; ok { 205 if bf, ok := BeeApp.Handlers.filters[BeforeExec]; ok {
206 filterType = "Before Exec"
207 filterTypes = append(filterTypes, filterType)
208 resultList := new([][]string)
209 for _, f := range bf { 209 for _, f := range bf {
210 210
211 var result = []string{ 211 var result = []string{
212 fmt.Sprintf(""),
213 fmt.Sprintf("%s", f.pattern), 212 fmt.Sprintf("%s", f.pattern),
214 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), 213 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
215 } 214 }
216 *resultList = append(*resultList, result) 215 *resultList = append(*resultList, result)
217
218 } 216 }
217 filterTypeData[filterType] = resultList
219 } 218 }
220 result = []string{
221 fmt.Sprintf("success"),
222 fmt.Sprintf("AfterExec Exec"),
223 fmt.Sprintf(""),
224 }
225 *resultList = append(*resultList, result)
226 219
227 if bf, ok := BeeApp.Handlers.filters[AfterExec]; ok { 220 if bf, ok := BeeApp.Handlers.filters[AfterExec]; ok {
221 filterType = "After Exec"
222 filterTypes = append(filterTypes, filterType)
223 resultList := new([][]string)
228 for _, f := range bf { 224 for _, f := range bf {
229 225
230 var result = []string{ 226 var result = []string{
231 fmt.Sprintf(""),
232 fmt.Sprintf("%s", f.pattern), 227 fmt.Sprintf("%s", f.pattern),
233 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), 228 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
234 } 229 }
235 *resultList = append(*resultList, result) 230 *resultList = append(*resultList, result)
236
237 } 231 }
232 filterTypeData[filterType] = resultList
238 } 233 }
239 result = []string{
240 fmt.Sprintf("success"),
241 fmt.Sprintf("Finish Router"),
242 fmt.Sprintf(""),
243 }
244 *resultList = append(*resultList, result)
245 234
246 if bf, ok := BeeApp.Handlers.filters[FinishRouter]; ok { 235 if bf, ok := BeeApp.Handlers.filters[FinishRouter]; ok {
236 filterType = "Finish Router"
237 filterTypes = append(filterTypes, filterType)
238 resultList := new([][]string)
247 for _, f := range bf { 239 for _, f := range bf {
248 240
249 var result = []string{ 241 var result = []string{
250 fmt.Sprintf(""),
251 fmt.Sprintf("%s", f.pattern), 242 fmt.Sprintf("%s", f.pattern),
252 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), 243 fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
253 } 244 }
254 *resultList = append(*resultList, result) 245 *resultList = append(*resultList, result)
255
256 } 246 }
247 filterTypeData[filterType] = resultList
257 } 248 }
258 } 249 }
259 data["Content"] = resultList 250
251 content["Data"] = filterTypeData
252 content["Methods"] = filterTypes
253
254 data["Content"] = content
260 data["Title"] = "Filters" 255 data["Title"] = "Filters"
261 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) 256 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
262 tmpl = template.Must(tmpl.Parse(routerAndFilterTpl)) 257 tmpl = template.Must(tmpl.Parse(routerAndFilterTpl))
...@@ -281,7 +276,6 @@ func printTree(resultList *[][]string, t *Tree) { ...@@ -281,7 +276,6 @@ func printTree(resultList *[][]string, t *Tree) {
281 if v, ok := l.runObject.(*controllerInfo); ok { 276 if v, ok := l.runObject.(*controllerInfo); ok {
282 if v.routerType == routerTypeBeego { 277 if v.routerType == routerTypeBeego {
283 var result = []string{ 278 var result = []string{
284 fmt.Sprintf(""),
285 fmt.Sprintf("%s", v.pattern), 279 fmt.Sprintf("%s", v.pattern),
286 fmt.Sprintf("%s", v.methods), 280 fmt.Sprintf("%s", v.methods),
287 fmt.Sprintf("%s", v.controllerType), 281 fmt.Sprintf("%s", v.controllerType),
...@@ -289,7 +283,6 @@ func printTree(resultList *[][]string, t *Tree) { ...@@ -289,7 +283,6 @@ func printTree(resultList *[][]string, t *Tree) {
289 *resultList = append(*resultList, result) 283 *resultList = append(*resultList, result)
290 } else if v.routerType == routerTypeRESTFul { 284 } else if v.routerType == routerTypeRESTFul {
291 var result = []string{ 285 var result = []string{
292 fmt.Sprintf(""),
293 fmt.Sprintf("%s", v.pattern), 286 fmt.Sprintf("%s", v.pattern),
294 fmt.Sprintf("%s", v.methods), 287 fmt.Sprintf("%s", v.methods),
295 fmt.Sprintf(""), 288 fmt.Sprintf(""),
...@@ -297,7 +290,6 @@ func printTree(resultList *[][]string, t *Tree) { ...@@ -297,7 +290,6 @@ func printTree(resultList *[][]string, t *Tree) {
297 *resultList = append(*resultList, result) 290 *resultList = append(*resultList, result)
298 } else if v.routerType == routerTypeHandler { 291 } else if v.routerType == routerTypeHandler {
299 var result = []string{ 292 var result = []string{
300 fmt.Sprintf(""),
301 fmt.Sprintf("%s", v.pattern), 293 fmt.Sprintf("%s", v.pattern),
302 fmt.Sprintf(""), 294 fmt.Sprintf(""),
303 fmt.Sprintf(""), 295 fmt.Sprintf(""),
...@@ -352,13 +344,15 @@ func profIndex(rw http.ResponseWriter, r *http.Request) { ...@@ -352,13 +344,15 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
352 func healthcheck(rw http.ResponseWriter, req *http.Request) { 344 func healthcheck(rw http.ResponseWriter, req *http.Request) {
353 data := make(map[interface{}]interface{}) 345 data := make(map[interface{}]interface{})
354 346
355 resultList := new([][]string) 347 var result = []string{}
356 var result = []string{ 348 fields := []string{
357 fmt.Sprintf("header"),
358 fmt.Sprintf("Name"), 349 fmt.Sprintf("Name"),
350 fmt.Sprintf("Message"),
359 fmt.Sprintf("Status"), 351 fmt.Sprintf("Status"),
360 } 352 }
361 *resultList = append(*resultList, result) 353 resultList := new([][]string)
354
355 content := make(map[string]interface{})
362 356
363 for name, h := range toolbox.AdminCheckList { 357 for name, h := range toolbox.AdminCheckList {
364 if err := h.Check(); err != nil { 358 if err := h.Check(); err != nil {
...@@ -379,7 +373,9 @@ func healthcheck(rw http.ResponseWriter, req *http.Request) { ...@@ -379,7 +373,9 @@ func healthcheck(rw http.ResponseWriter, req *http.Request) {
379 *resultList = append(*resultList, result) 373 *resultList = append(*resultList, result)
380 } 374 }
381 375
382 data["Content"] = resultList 376 content["Fields"] = fields
377 content["Data"] = resultList
378 data["Content"] = content
383 data["Title"] = "Health Check" 379 data["Title"] = "Health Check"
384 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) 380 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
385 tmpl = template.Must(tmpl.Parse(healthCheckTpl)) 381 tmpl = template.Must(tmpl.Parse(healthCheckTpl))
...@@ -410,17 +406,17 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) { ...@@ -410,17 +406,17 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
410 } 406 }
411 407
412 // List Tasks 408 // List Tasks
409 content := make(map[string]interface{})
413 resultList := new([][]string) 410 resultList := new([][]string)
414 var result = []string{ 411 var result = []string{}
415 fmt.Sprintf("header"), 412 var fields = []string{
416 fmt.Sprintf("Task Name"), 413 fmt.Sprintf("Task Name"),
417 fmt.Sprintf("Task Spec"), 414 fmt.Sprintf("Task Spec"),
418 fmt.Sprintf("Task Function"), 415 fmt.Sprintf("Task Function"),
416 fmt.Sprintf(""),
419 } 417 }
420 *resultList = append(*resultList, result)
421 for tname, tk := range toolbox.AdminTaskList { 418 for tname, tk := range toolbox.AdminTaskList {
422 result = []string{ 419 result = []string{
423 fmt.Sprintf(""),
424 fmt.Sprintf("%s", tname), 420 fmt.Sprintf("%s", tname),
425 fmt.Sprintf("%s", tk.GetStatus()), 421 fmt.Sprintf("%s", tk.GetStatus()),
426 fmt.Sprintf("%s", tk.GetPrev().String()), 422 fmt.Sprintf("%s", tk.GetPrev().String()),
...@@ -428,7 +424,9 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) { ...@@ -428,7 +424,9 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
428 *resultList = append(*resultList, result) 424 *resultList = append(*resultList, result)
429 } 425 }
430 426
431 data["Content"] = resultList 427 content["Fields"] = fields
428 content["Data"] = resultList
429 data["Content"] = content
432 data["Title"] = "Tasks" 430 data["Title"] = "Tasks"
433 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) 431 tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
434 tmpl = template.Must(tmpl.Parse(tasksTpl)) 432 tmpl = template.Must(tmpl.Parse(tasksTpl))
......
...@@ -61,31 +61,35 @@ var gcAjaxTpl = ` ...@@ -61,31 +61,35 @@ var gcAjaxTpl = `
61 {{end}} 61 {{end}}
62 ` 62 `
63 63
64 var qpsTpl = ` 64 var qpsTpl = `{{define "content"}}
65 {{define "content"}}
66 <h1>Requests statistics</h1> 65 <h1>Requests statistics</h1>
67 <table class="table table-striped table-hover "> 66 <table class="table table-striped table-hover ">
68 {{range $i, $slice := .Content}} 67 <thead>
69 <tr> 68 <tr>
70 {{range $j, $elem := $slice}} 69 {{range .Content.Fields}}
71 {{if eq $i 0}} 70 <th>
72 <th> 71 {{.}}
73 {{else}} 72 </th>
74 <td> 73 {{end}}
75 {{end}} 74 </tr>
76 {{$elem}} 75 </thead>
77 {{if eq $i 0}} 76
78 </th> 77 <tbody>
79 {{else}} 78 {{range $i, $elem := .Content.Data}}
80 </td> 79
81 {{end}} 80 <tr>
82 {{end}} 81 {{range $elem}}
82 <td>
83 {{.}}
84 </td>
85 {{end}}
86 </tr>
87
88 {{end}}
89 </tbody>
83 90
84 </tr>
85 {{end}}
86 </table> 91 </table>
87 {{end}} 92 {{end}}`
88 `
89 93
90 var configTpl = ` 94 var configTpl = `
91 {{define "content"}} 95 {{define "content"}}
...@@ -98,49 +102,51 @@ var configTpl = ` ...@@ -98,49 +102,51 @@ var configTpl = `
98 {{end}} 102 {{end}}
99 ` 103 `
100 104
101 var routerAndFilterTpl = ` 105 var routerAndFilterTpl = `{{define "content"}}
102 {{define "content"}} 106
103 107
104 <h1>{{.Title}}</h1> 108 <h1>{{.Title}}</h1>
105 <table class="table table-striped table-hover ">
106 {{range $i, $slice := .Content}}
107 <tr>
108 109
109 {{ $header := index $slice 0}} 110 {{range .Content.Methods}}
110 {{if eq "header" $header }} 111
111 {{range $j, $elem := $slice}} 112 <div class="panel panel-default">
112 {{if ne $j 0}} 113 <div class="panel-heading lead success"><strong>{{.}}</strong></div>
114 <div class="panel-body">
115 <table class="table table-striped table-hover ">
116 <thead>
117 <tr>
118 {{range $.Content.Fields}}
113 <th> 119 <th>
114 {{$elem}} 120 {{.}}
115 </th>
116 {{end}}
117 {{end}}
118 {{else if eq "success" $header}}
119 {{range $j, $elem := $slice}}
120 {{if ne $j 0}}
121 <th class="success">
122 {{$elem}}
123 </th> 121 </th>
124 {{end}} 122 {{end}}
125 {{end}} 123 </tr>
126 {{else}} 124 </thead>
127 {{range $j, $elem := $slice}} 125
128 {{if ne $j 0}} 126 <tbody>
127 {{$slice := index $.Content.Data .}}
128 {{range $i, $elem := $slice}}
129
130 <tr>
131 {{range $elem}}
129 <td> 132 <td>
130 {{$elem}} 133 {{.}}
131 </td> 134 </td>
132 {{end}} 135 {{end}}
136 </tr>
137
133 {{end}} 138 {{end}}
134 {{end}} 139 </tbody>
135 140
136 </tr>
137 {{end}}
138 </table> 141 </table>
142 </div>
143 </div>
139 {{end}} 144 {{end}}
140 `
141 145
142 var tasksTpl = ` 146
143 {{define "content"}} 147 {{end}}`
148
149 var tasksTpl = `{{define "content"}}
144 150
145 <h1>{{.Title}}</h1> 151 <h1>{{.Title}}</h1>
146 152
...@@ -161,59 +167,51 @@ bg-warning ...@@ -161,59 +167,51 @@ bg-warning
161 167
162 168
163 <table class="table table-striped table-hover "> 169 <table class="table table-striped table-hover ">
164 {{range $i, $slice := .Content}} 170 <thead>
165 <tr> 171 <tr>
172 {{range .Content.Fields}}
173 <th>
174 {{.}}
175 </th>
176 {{end}}
177 </tr>
178 </thead>
166 179
167 {{ $header := index $slice 0}} 180 <tbody>
168 {{if eq "header" $header }} 181 {{range $i, $slice := .Content.Data}}
169 {{range $j, $elem := $slice}} 182 <tr>
170 {{if ne $j 0}} 183 {{range $slice}}
171 <th>
172 {{$elem}}
173 </th>
174 {{end}}
175 {{end}}
176 <th>
177 Run Task
178 </th>
179 {{else}}
180 {{range $j, $elem := $slice}}
181 {{if ne $j 0}}
182 <td> 184 <td>
183 {{$elem}} 185 {{.}}
184 </td> 186 </td>
185 {{end}} 187 {{end}}
186 {{end}}
187 <td> 188 <td>
188 <a class="btn btn-primary btn-sm" href="/task?taskname={{index $slice 1}}">Run</a> 189 <a class="btn btn-primary btn-sm" href="/task?taskname={{index $slice 1}}">Run</a>
189 </td> 190 </td>
190 {{end}}
191
192 </tr> 191 </tr>
193 {{end}} 192 {{end}}
193 </tbody>
194 </table> 194 </table>
195 {{end}} 195
196 ` 196 {{end}}`
197 197
198 var healthCheckTpl = ` 198 var healthCheckTpl = `
199 {{define "content"}} 199 {{define "content"}}
200 200
201 <h1>{{.Title}}</h1> 201 <h1>{{.Title}}</h1>
202 <table class="table table-striped table-hover "> 202 <table class="table table-striped table-hover ">
203 {{range $i, $slice := .Content}} 203 <thead>
204
205 {{ $header := index $slice 0}}
206 {{if eq "header" $header }}
207 <tr> 204 <tr>
208 {{range $j, $elem := $slice}} 205 {{range .Content.Fields}}
209 {{if ne $j 0}}
210 <th> 206 <th>
211 {{$elem}} 207 {{.}}
212 </th> 208 </th>
213 {{end}} 209 {{end}}
214 {{end}}
215 </tr> 210 </tr>
216 {{else}} 211 </thead>
212 <tbody>
213 {{range $i, $slice := .Content.Data}}
214 {{ $header := index $slice 0}}
217 {{ if eq "success" $header}} 215 {{ if eq "success" $header}}
218 <tr class="success"> 216 <tr class="success">
219 {{else if eq "error" $header}} 217 {{else if eq "error" $header}}
...@@ -228,10 +226,13 @@ var healthCheckTpl = ` ...@@ -228,10 +226,13 @@ var healthCheckTpl = `
228 </td> 226 </td>
229 {{end}} 227 {{end}}
230 {{end}} 228 {{end}}
229 <td>
230 {{$header}}
231 </td>
231 </tr> 232 </tr>
232 {{end}} 233 {{end}}
233 234
234 {{end}} 235 </tbody>
235 </table> 236 </table>
236 {{end}}` 237 {{end}}`
237 238
...@@ -251,7 +252,8 @@ Welcome to Beego Admin Dashboard ...@@ -251,7 +252,8 @@ Welcome to Beego Admin Dashboard
251 252
252 </title> 253 </title>
253 254
254 <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"> 255 <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
256 <link href="//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.css" rel="stylesheet">
255 257
256 <style type="text/css"> 258 <style type="text/css">
257 ul.nav li.dropdown:hover > ul.dropdown-menu { 259 ul.nav li.dropdown:hover > ul.dropdown-menu {
...@@ -336,9 +338,17 @@ Healthcheck ...@@ -336,9 +338,17 @@ Healthcheck
336 {{template "content" .}} 338 {{template "content" .}}
337 </div> 339 </div>
338 340
339 <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> 341 <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
340 <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> 342 <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
343 <script src="//cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
344 <script src="//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.js
345 "></script>
341 346
347 <script type="text/javascript">
348 $(document).ready(function() {
349 $('.table').dataTable();
350 });
351 </script>
342 {{template "scripts" .}} 352 {{template "scripts" .}}
343 </body> 353 </body>
344 </html> 354 </html>
......
...@@ -83,13 +83,16 @@ func (m *UrlMap) AddStatistics(requestMethod, requestUrl, requestController stri ...@@ -83,13 +83,16 @@ func (m *UrlMap) AddStatistics(requestMethod, requestUrl, requestController stri
83 } 83 }
84 84
85 // put url statistics result in io.Writer 85 // put url statistics result in io.Writer
86 func (m *UrlMap) GetMap() [][]string { 86 func (m *UrlMap) GetMap() map[string]interface{} {
87 m.lock.RLock() 87 m.lock.RLock()
88 defer m.lock.RUnlock() 88 defer m.lock.RUnlock()
89
90 var fields = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"}
91
89 resultLists := make([][]string, 0) 92 resultLists := make([][]string, 0)
93 content := make(map[string]interface{})
94 content["Fields"] = fields
90 95
91 var result = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"}
92 resultLists = append(resultLists, result)
93 for k, v := range m.urlmap { 96 for k, v := range m.urlmap {
94 for kk, vv := range v { 97 for kk, vv := range v {
95 result := []string{ 98 result := []string{
...@@ -104,7 +107,8 @@ func (m *UrlMap) GetMap() [][]string { ...@@ -104,7 +107,8 @@ func (m *UrlMap) GetMap() [][]string {
104 resultLists = append(resultLists, result) 107 resultLists = append(resultLists, result)
105 } 108 }
106 } 109 }
107 return resultLists 110 content["Data"] = resultLists
111 return content
108 } 112 }
109 113
110 // global statistics data map 114 // global statistics data map
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!