wireway 202009261823 → 202101191029
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -0
- data/app/controllers/wireway/restful_controller.rb +26 -3
- data/app/views/layouts/wireway/application.html.erb +13 -1
- data/app/views/wireway/restful/ui.html.erb +413 -0
- data/config/routes.rb +4 -1
- data/{app/models/wireway/business_logic/restful.rb → lib/wireway/core/request.rb} +68 -20
- data/lib/wireway/core/standard.rb +145 -0
- data/lib/wireway/engine.rb +2 -0
- data/lib/wireway/spark.rb +21 -0
- metadata +6 -4
- data/app/models/wireway/spark.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09bb1a699b7c5117129b68d40c7697dadba11e6cc9cba425d83d28cdc6bfbd04'
|
4
|
+
data.tar.gz: fa07b6ec87843f8ea6d9057d03b95c5d110da340acf0b721dc646a4773eff707
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e9c4061d44c8f66773787c3946d0a4adcac4b48f9e7aac13662d8e11d271698f789631558fed26812ce114a4023b7c697cbe2864430118bfb02689090bf6c0e
|
7
|
+
data.tar.gz: 4fd0a7be8f36f7833b309ab0a7d1df3dedd1fc0122f93a5d8416370ed3d876f30ddd747ea5bf16238123483049b602a8f6e794ee83e77914e08ff0192c5b6258
|
data/README.md
CHANGED
@@ -1,13 +1,36 @@
|
|
1
1
|
module Wireway
|
2
2
|
class RestfulController < ApplicationController
|
3
|
-
|
3
|
+
|
4
|
+
def exposed_api
|
5
|
+
res = Wireway::Core::Request::platforms_exposed_api
|
6
|
+
render json: res[1]
|
7
|
+
end
|
8
|
+
|
9
|
+
def request_api_params
|
10
|
+
return render json: {success: false, result: '平台标识(platform_code)不能为空'} unless params[:platform_code]
|
11
|
+
return render json: {success: false, result: '接口标识(api_code)不能为空'} unless params[:api_code]
|
12
|
+
|
13
|
+
res = Wireway::Core::Request::request_api_params(platform_code: params[:platform_code], api_code: params[:api_code])
|
14
|
+
return render json: {success: false, result: res[1]} unless res[0]
|
15
|
+
|
16
|
+
res[1][:request_params] << {key: 'platform_code', name: '平台标识', explain: '接口所属平台标识', example: params[:platform_code], default: nil, value_type: 'string', necessary: true}
|
17
|
+
render json: res[1]
|
18
|
+
end
|
19
|
+
|
20
|
+
def request_api_result
|
4
21
|
# TODO 初步了解为rails5的安全机制 去除存在风险 暂时先这样
|
5
22
|
args = params.permit!.to_hash.reject!{|key| ["action", "controller"].include?(key)}.deep_symbolize_keys
|
6
23
|
|
7
|
-
res = Wireway::Spark.send(args[:
|
8
|
-
|
24
|
+
res = Wireway::Spark.send(args[:platform_code], args)
|
25
|
+
return (render html: res[1]) if res[1].is_a?(String)
|
26
|
+
tmp = {success: res[0]}
|
27
|
+
tmp.merge!(res[1])
|
9
28
|
(tmp.merge!(res[2]) rescue nil) if res[2].present?
|
10
29
|
render json: tmp.merge!(tmp)
|
11
30
|
end
|
31
|
+
|
32
|
+
def ui
|
33
|
+
end
|
34
|
+
|
12
35
|
end
|
13
36
|
end
|
@@ -4,13 +4,25 @@
|
|
4
4
|
<title>Wireway</title>
|
5
5
|
<%= csrf_meta_tags %>
|
6
6
|
<%= csp_meta_tag %>
|
7
|
+
<%=
|
8
|
+
res = Wireway::Spark.dashboard(api_code: :publish_other_request_assets, rely_assets: ["bootstrap_4", "chart_js", "jQuery_3_5_1", "amcharts_4", "google_charts", "highcharts", "space", "ff4c00"])
|
9
|
+
res[1].html_safe if res[0]
|
10
|
+
%>
|
7
11
|
|
8
12
|
<%= stylesheet_link_tag "wireway/application", media: "all" %>
|
9
13
|
<%= javascript_include_tag "wireway/application" %>
|
10
14
|
</head>
|
11
15
|
<body>
|
16
|
+
<div class="container pt-3 main_title" id="space">
|
12
17
|
|
13
|
-
|
18
|
+
<% flash.each do |state, message| %>
|
19
|
+
<div class="alert <%= (state == 'error') ? 'alert-danger' : 'alert-success' %> alert-dismissable fade show">
|
20
|
+
<button type="button" class="close" data-dismiss="alert">×</button>
|
21
|
+
<%= message %>
|
22
|
+
</div>
|
23
|
+
<% end %>
|
14
24
|
|
25
|
+
<%= yield %>
|
26
|
+
</div>
|
15
27
|
</body>
|
16
28
|
</html>
|
@@ -0,0 +1,413 @@
|
|
1
|
+
<div id='exposed_api'>
|
2
|
+
<div id='exposed_api_tag_cloud'></div>
|
3
|
+
<div id='exposed_api_jumbotron'></div>
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<div id='current_api' class='input-group mb-3'>
|
7
|
+
<select id="current_api_select" class="form-control" onchange='ui.current_api.change()'>
|
8
|
+
<option value=''>请选择具体api</option>
|
9
|
+
</select>
|
10
|
+
|
11
|
+
<div class="input-group-append">
|
12
|
+
<button class="btn btn-danger" type="button" onclick="ui.api_forms.reset_params_value()" id='current_api_reset_params_value' disabled=true>重置</button>
|
13
|
+
<button class="btn btn-primary" type="button" onclick="ui.api_forms.submit();" id='current_api_submit_button' disabled=true>提交</button>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div id='api_forms'></div>
|
18
|
+
|
19
|
+
<div id='api_results'></div>
|
20
|
+
|
21
|
+
<div id='readme' class='text-center'>
|
22
|
+
<hr>
|
23
|
+
<p>页面所涉及操作均可通过restful请求(详细信息参考README或F12),该页面仅为接口数据展示/交互.</p>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<script type="text/javascript">
|
27
|
+
ui = new Object()
|
28
|
+
exposed_api_ = []
|
29
|
+
// ====== 开放接口相关开始 ======
|
30
|
+
ui.exposed_api = $('#exposed_api')
|
31
|
+
ui.exposed_api.all = function () {
|
32
|
+
return exposed_api_
|
33
|
+
}
|
34
|
+
ui.exposed_api.add = function (item) {
|
35
|
+
exposed_api_.push(item);
|
36
|
+
}
|
37
|
+
|
38
|
+
ui.exposed_api.jumbotron = $('#exposed_api_jumbotron')
|
39
|
+
ui.exposed_api.jumbotron.add = function (platform_code, platform) {
|
40
|
+
jumbotron = document.createElement('div')
|
41
|
+
jumbotron.setAttribute('class', 'jumbotron')
|
42
|
+
|
43
|
+
h1 = document.createElement('h3')
|
44
|
+
h1.innerHTML = platform.name
|
45
|
+
jumbotron.appendChild(h1)
|
46
|
+
|
47
|
+
p = document.createElement('p')
|
48
|
+
p.innerHTML = platform.explain
|
49
|
+
jumbotron.appendChild(p)
|
50
|
+
|
51
|
+
apiButtons = document.createElement('div')
|
52
|
+
apiButtons.setAttribute('id', 'api_buttons_'+platform_code)
|
53
|
+
buttonColors = ['btn-primary','btn-success','btn-info','btn-warning','btn-danger','btn-secondary','btn-dark','btn-light']
|
54
|
+
|
55
|
+
jQuery.each(platform.exposed_api, function(key, info) {
|
56
|
+
button = document.createElement('button')
|
57
|
+
button.setAttribute('type', 'button')
|
58
|
+
buttonColor = buttonColors[Math.floor((Math.random()*buttonColors.length))]
|
59
|
+
button.setAttribute('class', 'btn ml-2 mb-2 '+buttonColor)
|
60
|
+
button.setAttribute('onclick', "ui.current_api.change('"+platform_code+"', '"+key+"')")
|
61
|
+
button.innerHTML = info.name
|
62
|
+
apiButtons.appendChild(button)
|
63
|
+
})
|
64
|
+
|
65
|
+
jumbotron.appendChild(apiButtons)
|
66
|
+
this[0].appendChild(jumbotron)
|
67
|
+
}
|
68
|
+
|
69
|
+
ui.exposed_api.tag_cloud = $('#exposed_api_tag_cloud')
|
70
|
+
ui.exposed_api.tag_cloud.load = function () {
|
71
|
+
if (!ui.exposed_api.all()[0]) return;
|
72
|
+
|
73
|
+
tag_datas = {}
|
74
|
+
jQuery.each(ui.exposed_api.all(), function(index, item) {
|
75
|
+
zh_ratio = (Math.round(Math.random() * (20 - 10)) + 8)
|
76
|
+
tag_datas[item.name] = {key_word: '['+item.platform_code+']'+item.api_code, weight: zh_ratio}
|
77
|
+
// en_ratio = (Math.round(Math.random() * (10 - 5)) + 1)
|
78
|
+
// tag_datas[item.api_code] = {key_word: '['+item.platform_code+']'+item.api_code, weight: en_ratio}
|
79
|
+
})
|
80
|
+
|
81
|
+
params = {
|
82
|
+
tag_datas: tag_datas,
|
83
|
+
tag_url: "javascript:ui.current_api.change('{key_word}');",
|
84
|
+
url_target:"_self",
|
85
|
+
chart_style: "width: 100%; height: 35%;",
|
86
|
+
platform_code: 'dashboard',
|
87
|
+
api_code: 'chart_other_tag_cloud'
|
88
|
+
}
|
89
|
+
|
90
|
+
url = "<%= request_api_result_restful_index_path() %>"
|
91
|
+
space.network.ajax({type: 'Post', "url": url, "params" : params}, function (result) {
|
92
|
+
if (!result[0]) return;
|
93
|
+
ui.exposed_api.tag_cloud.html($('<div>').html(result[1]).text())
|
94
|
+
})
|
95
|
+
}
|
96
|
+
|
97
|
+
ui.exposed_api.package = function (platform_code, platform) {
|
98
|
+
jQuery.each(platform.exposed_api, function(key, info) {
|
99
|
+
ui.exposed_api.add({name: info.name, platform_code: platform_code, api_code: key, explain: info.explain})
|
100
|
+
})
|
101
|
+
|
102
|
+
ui.current_api.select.add(platform_code, platform)
|
103
|
+
ui.exposed_api.jumbotron.add(platform_code, platform)
|
104
|
+
}
|
105
|
+
|
106
|
+
ui.exposed_api.load = function () {
|
107
|
+
url = "<%= exposed_api_restful_index_path() %>"
|
108
|
+
space.network.ajax({"url": url}, function (result) {
|
109
|
+
if (!result[0]) return;
|
110
|
+
jQuery.each(result[1], function(platform_code, platform) {
|
111
|
+
ui.exposed_api.package(platform_code, platform)
|
112
|
+
})
|
113
|
+
})
|
114
|
+
}
|
115
|
+
// ====== 开放接口相关结束 ======
|
116
|
+
|
117
|
+
// ====== 当前选择api相关开始 ======
|
118
|
+
ui.current_api = $('#current_api')
|
119
|
+
|
120
|
+
ui.currentApi = function () {
|
121
|
+
option = $("#current_api_select option:selected")
|
122
|
+
if (!option.attr('platform_code')) return [false, '当前尚未选中api'];
|
123
|
+
return [true, {platform_code: option.attr('platform_code'), api_code: option.attr('api_code')}]
|
124
|
+
}
|
125
|
+
|
126
|
+
ui.current_api.change = function (platform_code, api_code) {
|
127
|
+
if (platform_code && api_code) {
|
128
|
+
$('#current_api_select').val('['+platform_code+']'+api_code)
|
129
|
+
}else if ((platform_code || '').indexOf("[") == 0) {
|
130
|
+
// tmp = platform_code.split('[')[1].split(']')
|
131
|
+
// return this.change(tmp[0], tmp[1])
|
132
|
+
$('#current_api_select').val(platform_code)
|
133
|
+
}
|
134
|
+
|
135
|
+
res = ui.currentApi()
|
136
|
+
if (!res[0]) {
|
137
|
+
$('#current_api_submit_button').attr("disabled","true");
|
138
|
+
$('#current_api_reset_params_value').attr("disabled","true");
|
139
|
+
return
|
140
|
+
}
|
141
|
+
$("#current_api_submit_button").removeAttr("disabled");
|
142
|
+
$("#current_api_reset_params_value").removeAttr("disabled");
|
143
|
+
ui.api_results.hide()
|
144
|
+
ui.api_forms.load({auto_load_result: true})
|
145
|
+
}
|
146
|
+
|
147
|
+
ui.current_api.select = $('#current_api_select')
|
148
|
+
ui.current_api.select.add = function (platform_code, platform) {
|
149
|
+
jQuery.each(platform.exposed_api, function(key, info) {
|
150
|
+
option = document.createElement('option')
|
151
|
+
option.setAttribute('value', '['+platform_code+']'+key)
|
152
|
+
option.setAttribute('platform_code', platform_code)
|
153
|
+
option.setAttribute('api_code', key)
|
154
|
+
option.innerHTML = '['+platform_code+'] '+info.name+'---'+info.explain
|
155
|
+
ui.current_api.select[0].appendChild(option)
|
156
|
+
})
|
157
|
+
}
|
158
|
+
// ====== 当前选择api相关结束 ======
|
159
|
+
|
160
|
+
// ====== api调用参数相关开始 ======
|
161
|
+
ui.api_forms = $('#api_forms')
|
162
|
+
|
163
|
+
ui.api_forms.current = function (params) {
|
164
|
+
|
165
|
+
res = ui.currentApi()
|
166
|
+
if (!res[0]) return [false, '当前尚未选择具体api接口'];
|
167
|
+
|
168
|
+
defaultValues = {auto_load: false}
|
169
|
+
params = $.extend({}, defaultValues, params)
|
170
|
+
|
171
|
+
target_id = 'api_forms_'+res[1].platform_code+'_'+res[1].api_code
|
172
|
+
target_object = $('#'+target_id)
|
173
|
+
if (params.auto_load && (!target_object[0])) this.load();
|
174
|
+
return [!!target_object[0], {id: target_id, object: target_object}]
|
175
|
+
}
|
176
|
+
|
177
|
+
ui.api_forms.hide = function () {
|
178
|
+
$("form[class='api_forms_item']").each(function(){ $(this).addClass('d-none')});
|
179
|
+
}
|
180
|
+
|
181
|
+
ui.api_forms.package = function (target_id, target_info) {
|
182
|
+
form = document.createElement('form')
|
183
|
+
form.setAttribute('class', 'api_forms_item')
|
184
|
+
form.setAttribute('id', target_id)
|
185
|
+
form.setAttribute('accept-charset', 'UTF-8')
|
186
|
+
|
187
|
+
table = document.createElement('table')
|
188
|
+
table.setAttribute('class', 'table table-bordered table-striped table-hover')
|
189
|
+
|
190
|
+
tr = document.createElement('tr')
|
191
|
+
tds = [
|
192
|
+
{class: 'text-center', name: '名称'},
|
193
|
+
{class: 'text-center', name: '参数键'},
|
194
|
+
{class: 'text-center w-25', name: '示例值'},
|
195
|
+
{class: 'text-center w-25', name: '说明'},
|
196
|
+
{class: 'text-center', name: '默认值'},
|
197
|
+
{class: 'text-center', name: '参数类型'},
|
198
|
+
{class: 'text-center', name: '是否必填'},
|
199
|
+
]
|
200
|
+
jQuery.each(tds, function(index, detail) {
|
201
|
+
td = document.createElement('td')
|
202
|
+
td.setAttribute('class', detail.class)
|
203
|
+
td.innerHTML = detail.name
|
204
|
+
tr.appendChild(td)
|
205
|
+
})
|
206
|
+
table.appendChild(tr)
|
207
|
+
|
208
|
+
jQuery.each(target_info.request_params, function(index, detail) {
|
209
|
+
tr = document.createElement('tr')
|
210
|
+
|
211
|
+
jQuery.each(['name', 'key'], function(index, key){
|
212
|
+
td = document.createElement('td')
|
213
|
+
td.setAttribute('class', 'text-center')
|
214
|
+
td.innerHTML = (detail[key] || '无')
|
215
|
+
tr.appendChild(td)
|
216
|
+
})
|
217
|
+
|
218
|
+
|
219
|
+
td = document.createElement('td')
|
220
|
+
input = document.createElement('input')
|
221
|
+
input.setAttribute('class', 'form-control')
|
222
|
+
input.setAttribute('name', detail.key)
|
223
|
+
if ((detail.example || '').constructor == Array){
|
224
|
+
input.setAttribute('value', JSON.stringify(detail.example))
|
225
|
+
}else{
|
226
|
+
input.setAttribute('value', detail.example || '')
|
227
|
+
}
|
228
|
+
td.appendChild(input)
|
229
|
+
tr.appendChild(td)
|
230
|
+
|
231
|
+
jQuery.each(['explain', 'default', 'value_type'], function(index, key){
|
232
|
+
td = document.createElement('td')
|
233
|
+
if (index == 2) td.setAttribute('class', 'text-center');
|
234
|
+
|
235
|
+
if ((detail[key] || '').constructor == Array){
|
236
|
+
td.innerHTML = JSON.stringify(detail[key])
|
237
|
+
}else{
|
238
|
+
td.innerHTML = (detail[key] || '无')
|
239
|
+
}
|
240
|
+
|
241
|
+
tr.appendChild(td)
|
242
|
+
})
|
243
|
+
|
244
|
+
td = document.createElement('td')
|
245
|
+
td.setAttribute('class', 'text-center')
|
246
|
+
td.innerHTML = detail.necessary ? '是' : '否'
|
247
|
+
tr.appendChild(td)
|
248
|
+
|
249
|
+
table.appendChild(tr)
|
250
|
+
})
|
251
|
+
|
252
|
+
form.appendChild(table)
|
253
|
+
this[0].appendChild(form)
|
254
|
+
}
|
255
|
+
|
256
|
+
ui.api_forms.load = async function (params) {
|
257
|
+
res = ui.currentApi()
|
258
|
+
if (!res[0]) return;
|
259
|
+
this.hide()
|
260
|
+
|
261
|
+
defaultValues = {auto_load_result: false}
|
262
|
+
params = $.extend({}, defaultValues, params)
|
263
|
+
|
264
|
+
target_id = 'api_forms_'+res[1].platform_code+'_'+res[1].api_code
|
265
|
+
target_object = $('#'+target_id)
|
266
|
+
if (target_object[0]){
|
267
|
+
target_object.removeClass('d-none')
|
268
|
+
res = ui.api_results.current({reload: false})
|
269
|
+
if (res[0]) if (res[1].object[0]) res[1].object.removeClass('d-none')
|
270
|
+
return
|
271
|
+
}
|
272
|
+
|
273
|
+
url = "<%= request_api_params_restful_index_path() %>"
|
274
|
+
space.network.ajax({"url": url, params: {platform_code: res[1].platform_code, api_code: res[1].api_code}}, function (result) {
|
275
|
+
if (!result[0]) return;
|
276
|
+
ui.api_forms.package(target_id, result[1])
|
277
|
+
})
|
278
|
+
|
279
|
+
if (params.auto_load_result) {
|
280
|
+
if (!ui.api_forms.current()[0]) {
|
281
|
+
for (let i = 0; i < 1000; i++) {
|
282
|
+
await space.other.sleep(1)
|
283
|
+
if (ui.api_forms.current()[0]) i=1000;
|
284
|
+
}
|
285
|
+
}
|
286
|
+
this.submit()
|
287
|
+
}
|
288
|
+
|
289
|
+
}
|
290
|
+
|
291
|
+
ui.api_forms.reset_params_value = function () {
|
292
|
+
res = this.current()
|
293
|
+
if (!res[0]) return res;
|
294
|
+
res[1].object[0].reset()
|
295
|
+
return [true, '']
|
296
|
+
}
|
297
|
+
|
298
|
+
ui.api_forms.submit = function () {
|
299
|
+
res = this.current()
|
300
|
+
if (!res[0]) return res;
|
301
|
+
|
302
|
+
url = "<%= request_api_result_restful_index_path() %>"
|
303
|
+
params = res[1].object.closest('form').serialize()
|
304
|
+
space.network.ajax({type: 'Post', "url": url, "params" : params}, function (result) {
|
305
|
+
if (!result[0]) return;
|
306
|
+
if (result[1].constructor === Object) {
|
307
|
+
ui.api_results.handle_object(result[1])
|
308
|
+
}else {
|
309
|
+
ui.api_results.handle_html(result[1])
|
310
|
+
}
|
311
|
+
|
312
|
+
})
|
313
|
+
}
|
314
|
+
|
315
|
+
// ====== api调用参数相关结束 ======
|
316
|
+
|
317
|
+
// ====== api返回结果相关开始 ======
|
318
|
+
ui.api_results = $('#api_results')
|
319
|
+
|
320
|
+
ui.api_results.current = function (params) {
|
321
|
+
defaultValues = {present: false, reload: true}
|
322
|
+
params = $.extend({}, defaultValues, params)
|
323
|
+
res = ui.currentApi()
|
324
|
+
if (!res[0]) return [false, '当前尚未选择具体api接口'];
|
325
|
+
target_id = 'api_results_'+res[1].platform_code+'_'+res[1].api_code
|
326
|
+
if (params.present) if (!$('#'+target_id)[0]) ui.api_forms.load();
|
327
|
+
if (params.reload) if ($('#'+target_id)[0]) $('#'+target_id).remove()
|
328
|
+
return [true, {id: target_id, object: $('#'+target_id)}]
|
329
|
+
}
|
330
|
+
|
331
|
+
ui.api_results.hide = function () {
|
332
|
+
$("div[class='api_results_item']").each(function(){ $(this).addClass('d-none')});
|
333
|
+
}
|
334
|
+
|
335
|
+
ui.api_results.handle_object = function (object) {
|
336
|
+
res = this.current()
|
337
|
+
if (!res[0]) return res;
|
338
|
+
this.hide()
|
339
|
+
|
340
|
+
div = document.createElement('div')
|
341
|
+
div.setAttribute('class', 'api_results_item')
|
342
|
+
div.setAttribute('id', res[1].id)
|
343
|
+
|
344
|
+
table = document.createElement('table')
|
345
|
+
table.setAttribute('class', 'table table-bordered table-striped table-hover')
|
346
|
+
|
347
|
+
tr = document.createElement('tr')
|
348
|
+
tds = [
|
349
|
+
{class: 'text-center', style: 'width: 15%;', name: '返回键'},
|
350
|
+
{class: 'text-center', style: '', name: '返回值'}
|
351
|
+
]
|
352
|
+
jQuery.each(tds, function(index, detail) {
|
353
|
+
td = document.createElement('td')
|
354
|
+
td.setAttribute('class', detail.class)
|
355
|
+
td.setAttribute('style', detail.style)
|
356
|
+
td.innerHTML = detail.name
|
357
|
+
tr.appendChild(td)
|
358
|
+
})
|
359
|
+
table.appendChild(tr)
|
360
|
+
|
361
|
+
jQuery.each(object, function(key, value) {
|
362
|
+
tr = document.createElement('tr')
|
363
|
+
|
364
|
+
td = document.createElement('td')
|
365
|
+
td.setAttribute('class', 'text-right')
|
366
|
+
td.innerHTML = key
|
367
|
+
tr.appendChild(td)
|
368
|
+
|
369
|
+
td = document.createElement('td')
|
370
|
+
td.setAttribute('class', 'text-left')
|
371
|
+
td.setAttribute('style', 'max-width: 500px')
|
372
|
+
td.innerHTML = '<pre><code>'+JSON.stringify(value, undefined, 2)+'</code></pre>'
|
373
|
+
tr.appendChild(td)
|
374
|
+
|
375
|
+
|
376
|
+
|
377
|
+
table.appendChild(tr)
|
378
|
+
})
|
379
|
+
|
380
|
+
div.appendChild(table)
|
381
|
+
this[0].appendChild(div)
|
382
|
+
}
|
383
|
+
|
384
|
+
ui.api_results.handle_html = function (html) {
|
385
|
+
res = this.current()
|
386
|
+
if (!res[0]) return res;
|
387
|
+
this.hide()
|
388
|
+
|
389
|
+
div = document.createElement('div')
|
390
|
+
div.setAttribute('class', 'api_results_item')
|
391
|
+
div.setAttribute('id', res[1].id)
|
392
|
+
// div.innerHTML = html
|
393
|
+
this[0].appendChild(div)
|
394
|
+
|
395
|
+
$('#'+res[1].id).html($('#'+res[1].id).html(html).text())
|
396
|
+
}
|
397
|
+
// ====== api返回结果相关结束 ======
|
398
|
+
|
399
|
+
async function main () {
|
400
|
+
ui.exposed_api.load()
|
401
|
+
|
402
|
+
if (!ui.exposed_api.all()[0]) {
|
403
|
+
for (let i = 0; i < 1000; i++) {
|
404
|
+
await space.other.sleep(10)
|
405
|
+
if (ui.exposed_api.all()[0]) i=1000;
|
406
|
+
}
|
407
|
+
}
|
408
|
+
ui.exposed_api.tag_cloud.load()
|
409
|
+
}
|
410
|
+
|
411
|
+
main()
|
412
|
+
|
413
|
+
</script>
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Wireway
|
2
|
-
module
|
3
|
-
module
|
2
|
+
module Core
|
3
|
+
module Request
|
4
4
|
extend self
|
5
5
|
|
6
6
|
$wireway_node_addresses = 404
|
@@ -17,32 +17,67 @@ module Wireway
|
|
17
17
|
hash = JSON.parse(result[1][:body]).deep_symbolize_keys
|
18
18
|
[true, hash]
|
19
19
|
end
|
20
|
-
|
21
|
-
|
20
|
+
|
21
|
+
return res unless res[0]
|
22
|
+
nodes = res[1].map{|key, value| [key, value[:nodes]]}.to_h
|
23
|
+
$wireway_node_addresses = [true, nodes]
|
22
24
|
end
|
23
25
|
|
26
|
+
def platforms_exposed_api
|
27
|
+
res = node_addresses
|
28
|
+
return res unless res[0]
|
29
|
+
exposed_api = {}
|
30
|
+
|
31
|
+
platforms = {:satcom => ["123.57.155.17:3113"], :dashboard => ['123.57.155.17:3111'], :black_box => ['123.57.155.17:3116']}
|
32
|
+
platforms.each do |platform_code, addresses|
|
33
|
+
route = "/#{platform_code}/restful/exposed_api"
|
34
|
+
res = get(addresses: addresses, route: route) do |result|
|
35
|
+
hash = JSON.parse(result[1][:body]).deep_symbolize_keys
|
36
|
+
exposed_api.merge!(hash) if hash.is_a?(Hash)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
[true, exposed_api]
|
41
|
+
end
|
42
|
+
|
43
|
+
def request_api_params(platform_code:, api_code:)
|
44
|
+
res = node_addresses
|
45
|
+
return res unless res[0]
|
46
|
+
addresses = res[1][platform_code.to_sym]
|
47
|
+
route = "/#{platform_code}/restful/request_api_params"
|
48
|
+
|
49
|
+
get(addresses: addresses, route: route, params: {api_code: api_code}) do |result|
|
50
|
+
hash = JSON.parse(result[1][:body]).deep_symbolize_keys
|
51
|
+
[true, hash]
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
24
56
|
def dashboard(**args)
|
25
57
|
params = {
|
26
58
|
response_type: 'json',
|
27
59
|
}.merge!(args)
|
28
60
|
route = '/dashboard/restful/request_api'
|
29
|
-
|
30
|
-
|
31
|
-
|
61
|
+
res = node_addresses
|
62
|
+
return res unless res[0]
|
63
|
+
post(addresses: res[1][:dashboard], route: route, params: params) do |result|
|
64
|
+
return [true, result[1][:body]] if (params[:response_type] != 'json')
|
32
65
|
body = JSON.parse(result[1][:body]).deep_symbolize_keys
|
33
66
|
return [false, body[:result]] unless body[:success]
|
34
|
-
[true, body[:
|
35
|
-
end
|
67
|
+
[true, body[:result]]
|
68
|
+
end
|
36
69
|
end
|
37
70
|
|
38
71
|
def satcom(**args)
|
39
72
|
params = {}.merge!(args)
|
40
73
|
route = '/satcom/restful/request_api'
|
41
|
-
|
42
|
-
|
74
|
+
res = node_addresses
|
75
|
+
return res unless res[0]
|
76
|
+
post(addresses: res[1][:satcom], route: route, params: params) do |result|
|
43
77
|
body = JSON.parse(result[1][:body]).deep_symbolize_keys
|
44
78
|
return [false, body[:result], body[:errors]].compact unless body[:success]
|
45
|
-
[true, body[:result]]
|
79
|
+
# [true, body[:result]]
|
80
|
+
[true, body]
|
46
81
|
end
|
47
82
|
end
|
48
83
|
|
@@ -50,14 +85,27 @@ module Wireway
|
|
50
85
|
params = {
|
51
86
|
local: false
|
52
87
|
}.merge!(args)
|
53
|
-
route = '/wireway/restful/
|
54
|
-
|
55
|
-
|
88
|
+
route = '/wireway/restful/request_api_result'
|
89
|
+
res = node_addresses
|
90
|
+
return res unless res[0]
|
91
|
+
post(addresses: res[1][:wireway], route: route, params: params) do |result|
|
56
92
|
body = JSON.parse(result[1][:body]).deep_symbolize_keys
|
57
93
|
return [false, body[:result], body[:errors]].compact unless body[:success]
|
58
94
|
[true, body[:result]]
|
59
95
|
end
|
60
|
-
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def black_box(**args)
|
99
|
+
params = {}.merge!(args)
|
100
|
+
route = '/black_box/restful/request_api'
|
101
|
+
res = node_addresses
|
102
|
+
return res unless res[0]
|
103
|
+
res = post(addresses: res[1][:black_box], route: route, params: params) do |result|
|
104
|
+
body = JSON.parse(result[1][:body]).deep_symbolize_keys
|
105
|
+
return [false, body[:result], body[:errors]].compact unless body[:success]
|
106
|
+
[true, body]
|
107
|
+
end
|
108
|
+
end
|
61
109
|
|
62
110
|
def get(addresses:, route:, params: {})
|
63
111
|
result = round_robin(addresses: addresses) do |address|
|
@@ -70,7 +118,7 @@ module Wireway
|
|
70
118
|
begin
|
71
119
|
yield result
|
72
120
|
rescue
|
73
|
-
return [false, '运行时结果处理异常', {errors: {message: $!.to_s, path: $@}}]
|
121
|
+
return [false, '[Wireway]运行时结果处理异常', {errors: {message: $!.to_s, path: $@}}]
|
74
122
|
end
|
75
123
|
end
|
76
124
|
|
@@ -83,7 +131,7 @@ module Wireway
|
|
83
131
|
begin
|
84
132
|
yield result
|
85
133
|
rescue
|
86
|
-
return [false, '运行时结果处理异常', {errors: {message: $!.to_s, path: $@}}]
|
134
|
+
return [false, '[Wireway]运行时结果处理异常', {errors: {message: $!.to_s, path: $@}}]
|
87
135
|
end
|
88
136
|
end
|
89
137
|
|
@@ -104,7 +152,7 @@ module Wireway
|
|
104
152
|
def get_response
|
105
153
|
begin
|
106
154
|
response = yield
|
107
|
-
return [false, "响应码异常:#{response.code}", {response: response}] unless (response.code == 200)
|
155
|
+
return [false, "[Wireway]响应码异常:#{response.code}", {response: response}] unless (response.code == 200)
|
108
156
|
|
109
157
|
hash = {code: 200}
|
110
158
|
res = handle_body_encode(body: response.body)
|
@@ -112,7 +160,7 @@ module Wireway
|
|
112
160
|
|
113
161
|
hash.merge!({body: res[1]})
|
114
162
|
rescue
|
115
|
-
return [false, '请求异常', {errors: {message: $!.to_s, path: $@}}]
|
163
|
+
return [false, '[Wireway]请求异常', {errors: {message: $!.to_s, path: $@}}]
|
116
164
|
end
|
117
165
|
|
118
166
|
[true, hash]
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module Wireway
|
2
|
+
# 接口请求参数标准
|
3
|
+
module Standard
|
4
|
+
extend self
|
5
|
+
|
6
|
+
# 全自检项检查
|
7
|
+
def inspect_all(ideal:, reality:)
|
8
|
+
ideal_reality = {ideal: ideal, reality: reality}
|
9
|
+
|
10
|
+
res = default_value(ideal_reality)
|
11
|
+
return res unless res[0]
|
12
|
+
|
13
|
+
res = value_type(ideal_reality)
|
14
|
+
return res unless res[0]
|
15
|
+
|
16
|
+
res = attribute_necessary(ideal_reality)
|
17
|
+
return res unless res[0]
|
18
|
+
|
19
|
+
# res = check_data_format(described: described, reality: reality)
|
20
|
+
# return res unless res[0]
|
21
|
+
[true, '']
|
22
|
+
end
|
23
|
+
|
24
|
+
# 参数项检查
|
25
|
+
def attribute_necessary(ideal:, reality:)
|
26
|
+
# 检查必须参数是否缺失
|
27
|
+
necessary_standards = ideal.select{|standard| standard[:necessary] == true}
|
28
|
+
necessary_standards.each do |standard|
|
29
|
+
key = standard[:key]
|
30
|
+
unless (reality[key.to_sym] || reality[key]).present?
|
31
|
+
return [false, "#{standard[:name]}(#{key})为必须项,不能为空"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# 检查参数值是否符合正则式要求
|
36
|
+
reality.each do |key, value|
|
37
|
+
standard = ideal.select{|standard| [key, key.to_sym, key.to_s].uniq.include?(standard[:key])}[0]
|
38
|
+
# return [false, "未找到关于参数:#{key} 的定义"] unless standard
|
39
|
+
next unless standard
|
40
|
+
|
41
|
+
if standard[:regular] && (value.to_s =~ standard[:regular]).nil?
|
42
|
+
tmp = "参数:#{standard[:name]}(#{key})的参数值(#{value})不满足要求"
|
43
|
+
tmp+= ", 请参考: #{standard[:explain]}" if standard[:explain].present?
|
44
|
+
tmp+= ", 示例值: #{standard[:example]}" if standard[:example].present?
|
45
|
+
tmp+= ", 默认值: #{standard[:default]}" if standard[:default].present?
|
46
|
+
tmp+='.'
|
47
|
+
return [false, tmp]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
[true, '']
|
52
|
+
end
|
53
|
+
|
54
|
+
# 参数默认值检查
|
55
|
+
def default_value(ideal:, reality:)
|
56
|
+
ideal.select{|standard| !standard[:default].nil?}.each do |standard|
|
57
|
+
unless reality[standard[:key].to_sym].present?
|
58
|
+
reality.merge!({standard[:key].to_sym => standard[:default]})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
[true, '']
|
63
|
+
end
|
64
|
+
|
65
|
+
# 参数值格式检查
|
66
|
+
def value_type(ideal:, reality:)
|
67
|
+
ideal.each do |standard|
|
68
|
+
unless standard[:value_type].present?
|
69
|
+
return [false, "自描述参数标准检查异常: #{standard[:name]}(#{standard[:key]})未设置对应参数值类型(value_type)."]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
ideal.each do |standard|
|
74
|
+
old_value = reality[standard[:key].to_sym]
|
75
|
+
|
76
|
+
case standard[:value_type].to_sym
|
77
|
+
when :string_or_array, :array_or_string
|
78
|
+
new_value = (JSON.parse(old_value) rescue false)
|
79
|
+
new_value = old_value.split(/, |,/) unless new_value
|
80
|
+
when :array
|
81
|
+
error_msg = [false, "参数:#{standard[:key]},参数类型不符合Json数组要求."]
|
82
|
+
next if old_value.is_a?(Array)
|
83
|
+
|
84
|
+
new_value = (JSON.parse(old_value) rescue (return error_msg))
|
85
|
+
return error_msg unless new_value.is_a?(Array)
|
86
|
+
when :key_value
|
87
|
+
error_msg = [false, "参数:#{standard[:key]},参数类型不符合Json键值对要求."]
|
88
|
+
next if old_value.is_a?(Hash)
|
89
|
+
|
90
|
+
new_value = (JSON.parse(old_value) rescue (return error_msg))
|
91
|
+
return error_msg unless new_value.is_a?(Hash)
|
92
|
+
when :boolean
|
93
|
+
new_value = [true, 'true', '1', 1].include?(old_value)
|
94
|
+
when :integer
|
95
|
+
max_value = standard[:max]
|
96
|
+
return [false, "参数:#{standard[:key]},参数值:#{old_value} 大于接口定义最大值:#{max_value}."] if max_value.present? && (old_value.to_i > max_value)
|
97
|
+
next if old_value.is_a?(Integer)
|
98
|
+
if old_value == '0'
|
99
|
+
new_value = 0
|
100
|
+
else
|
101
|
+
return [false, "参数:#{standard[:key]},参数类型不符合数字要求."] if ((old_value.to_i rescue 0) == 0)
|
102
|
+
new_value = old_value.to_i
|
103
|
+
end
|
104
|
+
else
|
105
|
+
next
|
106
|
+
end
|
107
|
+
|
108
|
+
unless (old_value == new_value)
|
109
|
+
reality.merge!({standard[:key].to_sym => new_value})
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
[true, '']
|
114
|
+
end
|
115
|
+
|
116
|
+
def check_data_format(described:, reality:)
|
117
|
+
data_format = {}
|
118
|
+
if (reality[:data_format] == ['original']) && (reality[:key_type] == 'zh')
|
119
|
+
described[:data_structure].map do |key, value|
|
120
|
+
data_format.merge!([[value, key]].to_h)
|
121
|
+
end
|
122
|
+
reality[:data_format] = data_format
|
123
|
+
return [true, '']
|
124
|
+
elsif (reality[:data_format] == ['original'])
|
125
|
+
described[:data_structure].each do |key, value|
|
126
|
+
data_format.merge!([[key, key]].to_h)
|
127
|
+
end
|
128
|
+
reality[:data_format] = data_format
|
129
|
+
return [true, '']
|
130
|
+
end
|
131
|
+
|
132
|
+
data_format = reality[:data_format]
|
133
|
+
data_format = data_format.map(&:to_sym)
|
134
|
+
data_structure = {}
|
135
|
+
described[:data_structure].map{|key, value| data_structure.merge!([[key, key], [value.to_sym, key]].to_h)}
|
136
|
+
hit_items = data_structure.select{|key, value| data_format.include?(key)}
|
137
|
+
missed = (data_format - hit_items.keys).join(',')
|
138
|
+
return [false, "所提供数据格式中:#{missed},未找到对应匹配数据项"] if missed.present?
|
139
|
+
|
140
|
+
reality[:data_format] = hit_items
|
141
|
+
[true, '']
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
data/lib/wireway/engine.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Wireway
|
2
|
+
module Spark
|
3
|
+
def self.method_missing(method_name, local: true, **args)
|
4
|
+
begin
|
5
|
+
target = Wireway::Core::Request
|
6
|
+
unless [true, 'true', 1, '1', 'yes'].include?(local)
|
7
|
+
return [false, "未找到名称为:#{method_name}的方法定义."] unless target.respond_to?(method_name)
|
8
|
+
end
|
9
|
+
res = target.send(method_name, args)
|
10
|
+
rescue
|
11
|
+
error_msg = [false, '[Wireway]请求异常', {errors: {message: $!.to_s, path: $@}}]
|
12
|
+
return error_msg unless [true, 'true', 1, '1', 'yes'].include?(local)
|
13
|
+
# 当以Gem形式的组件无法处理请求时,尝试请求线上版组件是否可以正常处理请求
|
14
|
+
# 即当gem出现问题时会请求线上服务 有利于断点排查
|
15
|
+
args.merge!(platform: method_name)
|
16
|
+
res = target.wireway(args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wireway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '202101191029'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ff4c00
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -91,13 +91,15 @@ files:
|
|
91
91
|
- app/jobs/wireway/application_job.rb
|
92
92
|
- app/mailers/wireway/application_mailer.rb
|
93
93
|
- app/models/wireway/application_record.rb
|
94
|
-
- app/models/wireway/business_logic/restful.rb
|
95
|
-
- app/models/wireway/spark.rb
|
96
94
|
- app/views/layouts/wireway/application.html.erb
|
95
|
+
- app/views/wireway/restful/ui.html.erb
|
97
96
|
- config/routes.rb
|
98
97
|
- lib/tasks/wireway_tasks.rake
|
99
98
|
- lib/wireway.rb
|
99
|
+
- lib/wireway/core/request.rb
|
100
|
+
- lib/wireway/core/standard.rb
|
100
101
|
- lib/wireway/engine.rb
|
102
|
+
- lib/wireway/spark.rb
|
101
103
|
- lib/wireway/version.rb
|
102
104
|
homepage: https://gitlab.com/ff4c00/space/-/tree/master/%E7%9F%A5%E8%AF%86%E4%BD%93%E7%B3%BB/%E5%BA%94%E7%94%A8%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/Rails/C919/wireway
|
103
105
|
licenses:
|
data/app/models/wireway/spark.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
module Wireway
|
2
|
-
module Spark
|
3
|
-
|
4
|
-
# Wireway::Spark.dashboard(api_code: :publish_other_request_assets, rely_assets: ["bootstrap_4", "jQuery_3_5_1", "chart_js"])
|
5
|
-
# Wireway::Spark.satcom(api_code: :finance_fund_base_info, code: '161725')
|
6
|
-
# Wireway::BusinessLogic::Restful::node_addresses
|
7
|
-
# Wireway::Spark.wireway(platform: :satcom, api_code: :finance_fund_base_info, code: '161725')
|
8
|
-
def self.method_missing(method_name, local: true, **args)
|
9
|
-
begin
|
10
|
-
target = Wireway::BusinessLogic::Restful
|
11
|
-
return [false, '未找到相关定义方法'] unless target.respond_to?(method_name)
|
12
|
-
res = target.send(method_name, args)
|
13
|
-
rescue
|
14
|
-
error_msg = [false, '请求异常', {errors: {message: $!.to_s, path: $@}}]
|
15
|
-
return error_msg unless [true, 'true', 1, '1', 'yes'].include?(local)
|
16
|
-
# 当以Gem形式的组件无法处理请求时,尝试请求线上版组件是否可以正常处理请求
|
17
|
-
# 即当gem出现问题时会请求线上服务 有利于断点排查
|
18
|
-
args.merge!(platform: method_name)
|
19
|
-
res = target.wireway(args)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|