sbd-npm 1.5.29 → 1.5.31

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.
package/constant.js CHANGED
@@ -196,12 +196,11 @@ const MenuList = [
196
196
  {'key': 'hk_hsi', 'name': '恒生指数', 'url': '/0x3135360dcf6896d681e5db9cd588bc7bd653ba32'},
197
197
  {'key': 'hk_hstech', 'name': '恒生科技指数', 'url': '/0x0c340f1dd3760b1b4b0034dc5a258d4e40c1469a'},
198
198
  {'key': 'hk_hsci', 'name': '恒生综合指数', 'url': '/0x3dd9fec342f81357a01e8b0f4a242e94892d5439'},
199
- {'key': 'hk_hsm25', 'name': '恒生中国25指数', 'url': '/0x51c9cebe97e898875fba107e53fad29c79e1a1bb'},
200
- {'key': 'hk_hsm100', 'name': '恒生中国100指数', 'url': '/0x759fcb84a0a322125df6748dffad66d7b2b44c2d'},
201
199
  {'key': 'hk_biotechnology', 'name': '生物科技', 'url': '/0xa131be85db2beb939e93207d0966c3710c7b761a'},
202
200
  {'key': 'hk_sell_short', 'name': '沽空排行', 'url': '/0x4ecddc987891875a42d206620cd97ca382613485'},
203
201
  {'key': 'hk_mutual', 'name': '港股通持股排行', 'url': '/0x310a47a6abd868f19cd3fdbf2f2566813cb45d57'},
204
- {'key': 'hk_institutional_positions', 'name': '机构持仓变化', 'url': '/0xe5606bba43cf85cc3870f3608fe556648ce13084'}
202
+ {'key': 'hk_institutional_positions', 'name': '机构持仓变化', 'url': '/0xe5606bba43cf85cc3870f3608fe556648ce13084'},
203
+ {'key': 'hk_prepare_mutual', 'name': '准入通股', 'url': '/0x737d14bafc0049c5a4b3a2ef34e6c2a8e37462bc'}
205
204
  ]
206
205
  },
207
206
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sbd-npm",
3
- "version": "1.5.29",
3
+ "version": "1.5.31",
4
4
  "description": "Stock Big Data",
5
5
  "author": "DHQ <dhq314@gmail.com>",
6
6
  "license": "ISC",
@@ -0,0 +1,412 @@
1
+ /**
2
+ * Copyright (C) 2015-present dhq <dhq314@gmail.com>
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * https://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ $(function () {
17
+
18
+ let Tweet = {
19
+
20
+ pageYOffset: 0,
21
+ user_data: {},
22
+ is_key_word_tweet: 0,
23
+ tweet_key_words: [],
24
+
25
+ init_tweet_status: function() {
26
+ let tweet_type = parseInt($("#tweet_type").val());
27
+ Util.post(location.pathname, {"action": "tweet_status", "tweet_type": tweet_type}, function (j) {
28
+ if (parseInt(j.tweet_type) === tweet_type) {
29
+ let request_arguments = Util.request_arguments();
30
+ let html = [], is_select = 0;
31
+ html.push("<option value='0'>用户</option>");
32
+ if (j.user_data) {
33
+ let uid = request_arguments.uid ? parseInt(request_arguments.uid) : 0;
34
+ j.user_data.forEach(function (item) {
35
+ Tweet.user_data[item.uid] = item.name;
36
+ let select_mark = "";
37
+ if (item.uid === uid) {
38
+ is_select = 1;
39
+ select_mark = "selected";
40
+ if (request_arguments.is_delete) {
41
+ $("#is_delete").prop ("checked", true);
42
+ }
43
+ }
44
+ html.push("<option ", select_mark ," value='", item.uid, "'>", item.name, "(", item.num, ")</option>");
45
+ });
46
+ $("#is_delete_string").html("是否已被删除(" + j.del_num + "/" + j.total_num + ")");
47
+ }
48
+ $("#uid").html(html.join(""));
49
+ if (request_arguments.tid && Util.is_digit(request_arguments.tid)) {
50
+ is_select = 1;
51
+ $("#tid").val (request_arguments.tid);
52
+ }
53
+ if (is_select === 1) {
54
+ Tweet.fetch_tweet_data();
55
+ }
56
+ if (j.key_words) {
57
+ Tweet.tweet_key_words = j.key_words;
58
+ let key_words = Tweet.tweet_key_words.map(item => "“" + item + "”").join("、");
59
+ $("#content").attr("data-original-title", "推文内容搜索,例如:" + key_words);
60
+ }
61
+ if (j.special_observe_uid_list) {
62
+ Tweet.special_observe_uid_list = j.special_observe_uid_list;
63
+ Tweet.raw_special_observe_uid_list = j.special_observe_uid_list;
64
+ }
65
+ $("#today_so_num").html(j.today_so_num && j.today_so_num > 0 ? ("(" + j.today_so_num + ")") : "");
66
+ $("#update_time").html(j.update_time && j.update_time > 0 ? ("&nbsp;(更新于:" + Util.seconds_to_format(j.update_time) + ")") : "");
67
+ let kwt_object = document.getElementById("key_word_tweet");
68
+ if (j.key_word_num && j.key_word_num > 0) {
69
+ if (!kwt_object) {
70
+ $("#today_new_tweet").after('<a href="#" id="key_word_tweet" class="btn btn-danger form-control">关键词(<span>' + j.key_word_num + '</span>)</a>');
71
+ $("#key_word_tweet").click(function() {
72
+ if (!Util.is_load) {
73
+ Tweet.is_key_word_tweet = 1;
74
+ Tweet.fetch_tweet_data();
75
+ }
76
+ });
77
+ }
78
+ } else if (kwt_object) {
79
+ kwt_object.remove();
80
+ }
81
+ let tts_object = document.getElementById("today_tweet_statistics");
82
+ if (j.today_num && j.today_num > 0) {
83
+ $("#today_num").html(j.today_num);
84
+ if (!tts_object) {
85
+ if (Util.is_mobile()) {
86
+ $("#query_data").after('<a id="today_tweet_statistics" data-toggle="modal" data-target=".today_tweet_statistics_modal" href="#" title="今日新帖统计分析"><i class="glyphicon glyphicon-info-sign"></i></a>');
87
+ } else {
88
+ $("#today_new_tweet").after('<div class="form-group"><a style="margin-top: 10px;" id="today_tweet_statistics" data-toggle="modal" data-target=".today_tweet_statistics_modal" href="#" title="今日新帖统计分析"><i class="glyphicon glyphicon-info-sign"></i></a></div>&nbsp;');
89
+ }
90
+ Util.init_modal_skeleton("today_tweet_statistics_modal");
91
+ $("#today_tweet_statistics_modal_title").html("今日新帖(" + j.today_num + ")统计分析");
92
+ $("#today_tweet_statistics_modal_body").parent().parent().removeClass("modal-xlg");
93
+ let ttsm_object = $('#today_tweet_statistics_modal');
94
+ ttsm_object.on('show.bs.modal', function (e) {
95
+ Util.show_loading();
96
+ Util.post(location.pathname, {"action": "today_tweet_statistics", "tweet_type": $("#tweet_type").val()}, function (j) {
97
+ let html = [], total_num = 0;
98
+ html.push('<div class="form-inline text-center">');
99
+ html.push('<div class="form-group text-left">');
100
+ j.data.forEach(function (item) {
101
+ total_num += item.num;
102
+ html.push('<a class="btn btn-default" data-val="', item.uid, '" style="margin-bottom: 10px;" href="#">', item.name, '(', item.num, ')</a>');
103
+ });
104
+ html.push('</div>');
105
+ html.push('<div class="form-group" style="margin: 10px 0;">');
106
+ html.push('<button type="button" class="btn btn-info" disabled>共 ', total_num, ' 条</button>');
107
+ html.push('</div>');
108
+ html.push('</div>');
109
+ $("#today_tweet_statistics_modal_body").html(html.join("")).find("a").each(function() {
110
+ $(this).click(function() {
111
+ Tweet.set_today_date();
112
+ $("#uid").val($(this).attr("data-val"));
113
+ $('#today_tweet_statistics_modal').modal('hide');
114
+ setTimeout(Tweet.fetch_tweet_data, 789);
115
+ });
116
+ });;
117
+ Util.hide_tips();
118
+ });
119
+ });
120
+ ttsm_object.on('hidden.bs.modal', function () {
121
+ $("#today_tweet_statistics_modal_body").html("");
122
+ Util.hide_tips();
123
+ });
124
+ }
125
+ } else {
126
+ $("#today_num").html(0);
127
+ if (tts_object) {
128
+ tts_object.remove();
129
+ }
130
+ }
131
+ } else {
132
+ Tweet.init_tweet_status();
133
+ }
134
+ });
135
+ },
136
+
137
+ fetch_tweet_data: function() {
138
+ Util.show_loading();
139
+ let payload = Tweet.get_payload();
140
+ payload["is_key_word_tweet"] = Tweet.is_key_word_tweet;
141
+ Util.post(location.pathname, payload, function (j) {
142
+ Tweet.render_tweet_html(j.data, 0);
143
+ Tweet.is_key_word_tweet = 0;
144
+ });
145
+ },
146
+
147
+ get_payload: function() {
148
+ let special_observe_uid = "";
149
+ if (Tweet.special_observe_uid_list && $("#is_special_observe").prop("checked")) {
150
+ special_observe_uid = Tweet.special_observe_uid_list.join(",");
151
+ }
152
+ return {
153
+ action: "tweet_search",
154
+ tweet_type: $("#tweet_type").val(),
155
+ content: $("#content").val(),
156
+ uid: $("#uid").val(),
157
+ tid: $("#tid").val(),
158
+ start_date: $("#tweet_start_date").val(),
159
+ end_date: $("#tweet_end_date").val(),
160
+ is_delete: $("#is_delete").prop("checked") ? 1 : 0,
161
+ special_observe_uid: special_observe_uid
162
+ };
163
+ },
164
+
165
+ render_tweet_html: function(data, render_type) {
166
+ if (data && data.length > 0) {
167
+ let html = [], regexp_pattern = null, is_simple = 0;
168
+ let key_word_array = Tweet.tweet_key_words.slice();
169
+ let key_word = $("#content").val().trim();
170
+ if (key_word) {
171
+ key_word_array.push(key_word);
172
+ }
173
+ if (key_word_array.length > 0) {
174
+ regexp_pattern = new RegExp("(" + key_word_array.join("|") + ")", "g");
175
+ }
176
+ let tweet_type = parseInt($("#tweet_type").val());
177
+ if (data.length > 2) {
178
+ is_simple = $("#is_simple").prop("checked") ? 1 : 0;
179
+ }
180
+ data.forEach(function (item) {
181
+ let url = "", user_url = "";
182
+ html.push('<li><div class="block"><div class="block_content">');
183
+ if (tweet_type === 2) {
184
+ url = "https://weibo.com/" + item.uid + "/" + item.id;
185
+ user_url = "https://weibo.com/u/" + item.uid;
186
+ } else {
187
+ if (item.uid > 0) {
188
+ if (item.mark.includes("/")) {
189
+ url = "https://xueqiu.com/" + item.mark;
190
+ } else {
191
+ url = "https://xueqiu.com/" + item.uid + "/" + item.id;
192
+ }
193
+ user_url = "https://xueqiu.com/u/" + item.uid;
194
+ } else {
195
+ url = "https://xueqiu.com/S/" + item.mark + "/" + item.id;
196
+ user_url = "https://xueqiu.com/S/" + item.mark;
197
+ item.user_name = (item.content.includes("公告及通告") || item.content.includes("自愿公告")) ? "公告" : "资讯";
198
+ }
199
+ }
200
+ item.content = item.content.replace(/\\/g, "");
201
+ if (regexp_pattern) {
202
+ item.content = item.content.replace(regexp_pattern, "<span class='label label-danger'>$1</span>");
203
+ //item.content = item.content.replace(new RegExp(key_word, "g"), "<span class='label label-danger'>" + key_word + "</span>");
204
+ }
205
+ item.content = item.content.replace(/thumb\.jpg/g, "custom.jpg");
206
+ if (is_simple === 1) {
207
+ //item.content = item.content.replace(/<img\b[^>]*>/gi, '');
208
+ item.content = item.content.replace(/<img\b(?![^>]*src\s*=\s*["'][^"']*emoji)[^>]*>/gi, '');
209
+ let paragraph_array = item.content.match(/<p[\s\S]*?<\/p>/g) || [];
210
+ if (paragraph_array.length > 4) {
211
+ item.content = paragraph_array.slice(0, 5).join('');
212
+ item.content += "...";
213
+ } else {
214
+ let line_break_count = (item.content.match(/<br\/?>/g) || []).length;
215
+ if (line_break_count > 4) {
216
+ let content_array = item.content.split(/<br\s*\/?>/);
217
+ item.content = content_array.slice(0, 5).join('<br>');
218
+ item.content += "<br>...";
219
+ }
220
+ }
221
+ } else {
222
+ if (item.pic) {
223
+ let pic_array = item.pic.split(",");
224
+ pic_array.forEach(function (pic) {
225
+ if (pic.includes("thumb.jpg")) {
226
+ pic = pic.replace("thumb.jpg", "custom.jpg");
227
+ } else if (!pic.includes("custom.jpg")) {
228
+ pic += "!custom.jpg";
229
+ }
230
+ if (!item.content.includes(pic)) {
231
+ item.content += "<br><img src='" + pic + "'>";
232
+ }
233
+ });
234
+ }
235
+ }
236
+ let user_name = "";
237
+ if (item.mark && Tweet.user_data[item.mark]) {
238
+ user_name = Util.pack_html_link("https://xueqiu.com/S/" + item.mark, Tweet.user_data[item.mark]) + " - ";
239
+ if (item.user_name) {
240
+ user_name += Util.pack_html_link(user_url, item.user_name);
241
+ } else if (Tweet.user_data[item.uid]) {
242
+ user_name += Util.pack_html_link(user_url, Tweet.user_data[item.uid]);
243
+ } else {
244
+ user_name += Util.pack_html_link(user_url, item.uid);
245
+ }
246
+ } else if (Tweet.user_data[item.uid]) {
247
+ user_name = Util.pack_html_link(user_url, Tweet.user_data[item.uid]);
248
+ } else {
249
+ user_name = Util.pack_html_link(user_url, item.uid);
250
+ }
251
+ if (item.status === 0) {
252
+ html.push('<h2 class="title">[', user_name, '] <b class="del_tweet">', Util.pack_html_link(url, url), '</b></h2>');
253
+ } else {
254
+ html.push('<h2 class="title">[', user_name, '] ', Util.pack_html_link(url, url), '</h2>');
255
+ }
256
+ html.push('<div class="byline"><span>', Util.seconds_to_format(item.create_time), '</span></div>');
257
+ html.push('<p class="excerpt">', item.content, '</p>');
258
+ html.push('</div></div></li>');
259
+ });
260
+ if (render_type === 1) {
261
+ $("#tweet_list").append(html.join(""));
262
+ } else {
263
+ $("#tweet_list").html(html.join(""));
264
+ }
265
+ $(".del_tweet a").each(function() {
266
+ $(this).css("color", "#a94442");
267
+ });
268
+ Util.hide_tips();
269
+ } else {
270
+ Util.hide_tips();
271
+ Util.show_tips("暂无数据!", 5000, "alert-danger");
272
+ }
273
+ },
274
+
275
+ render_special_observe_html() {
276
+ let html = [];
277
+ let so_uid_list = Tweet.special_observe_uid_list ? Tweet.special_observe_uid_list : [];
278
+ html.push('<div class="form-inline text-center">');
279
+ html.push('<div class="form-group text-left">');
280
+ $('#uid option').each(function() {
281
+ let uid = parseInt($(this).val());
282
+ if (uid > 0) {
283
+ let user_name = Util.strip_bracket_string($(this).text());
284
+ html.push('<label class="checkbox-inline" style="margin: 0 10px 5px 0;">');
285
+ html.push('<input type="checkbox" value="', uid, '" ', (so_uid_list.includes(uid) ? "checked" : ""), '> ', user_name);
286
+ html.push('</label>');
287
+ }
288
+ });
289
+ html.push('</div>');
290
+ html.push('<div class="form-group" style="margin: 10px 0;">');
291
+ html.push('<button id="all_so_uid" type="button" class="btn btn-info">全 选</button>&nbsp;&nbsp;');
292
+ html.push('<button id="reset_so_uid" type="button" class="btn btn-info">重 置</button>&nbsp;&nbsp;');
293
+ html.push('<button id="save_so_uid" type="button" class="btn btn-success">保 存</button>');
294
+ html.push('<span id="so_uid_tips"></span>');
295
+ html.push('</div>');
296
+ html.push('</div>');
297
+ $("#special_observe_modal_body").html(html.join(""));
298
+ $("#all_so_uid").click(function() {
299
+ document.querySelectorAll('#special_observe_modal_body input[type="checkbox"]').forEach(cb => {
300
+ cb.checked = true;
301
+ });
302
+ });
303
+ $("#reset_so_uid").click(function() {
304
+ if (Tweet.raw_special_observe_uid_list) {
305
+ document.querySelectorAll('#special_observe_modal_body input[type="checkbox"]').forEach(cb => {
306
+ let uid = parseInt(cb.value);
307
+ cb.checked = Tweet.raw_special_observe_uid_list.includes(uid) ? true : false;
308
+ });
309
+ }
310
+ });
311
+ $("#save_so_uid").click(function() {
312
+ $("#so_uid_tips").html("");
313
+ let so_uid_list = [];
314
+ document.querySelectorAll('#special_observe_modal_body input[type="checkbox"]:checked').forEach(cb => {
315
+ let uid = parseInt(cb.value);
316
+ if (uid > 0) {
317
+ so_uid_list.push(uid);
318
+ }
319
+ });
320
+ Tweet.special_observe_uid_list = so_uid_list;
321
+ $("#so_uid_tips").html("<b class='text-success'>保存成功!</b>");
322
+ });
323
+ },
324
+
325
+ set_today_date: function() {
326
+ let now = Util.now();
327
+ let date = new Date();
328
+ let hour = date.getHours();
329
+ let start_date = hour < 6 ? (now - Util.one_day_second) : now;
330
+ $('#tweet_start_date').data('daterangepicker').setStartDate(Util.seconds_to_format(start_date, "%Y-%m-%d"));
331
+ $('#tweet_end_date').data('daterangepicker').setStartDate(Util.seconds_to_format(now, "%Y-%m-%d"));
332
+ }
333
+
334
+ };
335
+
336
+ Util.init_date_range_picker("tweet_start_end_date", Tweet, "fetch_tweet_data");
337
+ $("#tweet_start_date").val("");
338
+ $("#tweet_end_date").val("");
339
+ $("#today_new_tweet").click(function() {
340
+ if (!Util.is_load) {
341
+ let today_num = parseInt($("#today_num").text());
342
+ if (today_num > 0) {
343
+ let uid = parseInt($("#uid").val());
344
+ if (uid === 0) {
345
+ Tweet.set_today_date();
346
+ }
347
+ Tweet.fetch_tweet_data();
348
+ } else {
349
+ Util.show_tips("今日暂无新帖", 4567, "alert-danger");
350
+ }
351
+ }
352
+ });
353
+ $("#tweet_type").change(function() {
354
+ Tweet.pageYOffset = 0;
355
+ $("#uid").html('<option value="0">Loading...</option>');
356
+ $("#tweet_list").html("");
357
+ Tweet.init_tweet_status();
358
+ });
359
+
360
+ Util.init_modal_skeleton("special_observe_modal");
361
+ $("#special_observe_modal_title").html("特别关注名单");
362
+ $("#special_observe_modal_body").parent().parent().removeClass("modal-xlg");
363
+ let som_object = $('#special_observe_modal');
364
+ som_object.on('show.bs.modal', function (e) {
365
+ Tweet.render_special_observe_html();
366
+ });
367
+ som_object.on('hidden.bs.modal', function () {
368
+ $("#special_observe_modal_body").html("");
369
+ Util.hide_tips();
370
+ });
371
+
372
+ Tweet.init_tweet_status();
373
+ $("#query_data").click(function() {
374
+ Tweet.fetch_tweet_data();
375
+ });
376
+ $("#is_simple").click(function() {
377
+ if ($('#tweet_list li').length > 0) {
378
+ Tweet.fetch_tweet_data();
379
+ }
380
+ });
381
+
382
+ // 触发下拉到底部时的事件
383
+ window.onscroll = function(ev) {
384
+ if (!Util.is_load && window.pageYOffset > Tweet.pageYOffset) {
385
+ if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
386
+ if (!document.getElementById("tweet_loading")) {
387
+ let create_time = 0;
388
+ $("#tweet_list li .byline").each(function() {
389
+ let ct = $(this).text();
390
+ ct = Util.format_to_second(ct);
391
+ if (ct > 0 && (create_time === 0 || create_time > ct)) {
392
+ create_time = ct;
393
+ }
394
+ });
395
+ if (create_time > 0) {
396
+ Tweet.pageYOffset = window.pageYOffset;
397
+ $('#tweet_list').append('<li id="tweet_loading"><div class="block"><div class="block_content text-center" style="font-size: 25px; line-height: 2em;">Loading...</div></div></li>');
398
+ Util.show_loading();
399
+ let payload = Tweet.get_payload();
400
+ payload["append_time"] = create_time;
401
+ Util.post(location.pathname, payload, function (j) {
402
+ $("#tweet_loading").remove();
403
+ Tweet.render_tweet_html(j.data, 1);
404
+ });
405
+ }
406
+ }
407
+ }
408
+ }
409
+ };
410
+ Util.hide_tips();
411
+
412
+ });
package/status.js CHANGED
@@ -1119,7 +1119,7 @@ $(function () {
1119
1119
 
1120
1120
  init_machine_instruction_modal: function () {
1121
1121
  Util.init_modal_skeleton("machine_instruction_modal");
1122
- $("#machine_instruction_modal_title").html("添加任务<span style='color: #BDBDBD;' id='machine_instruction_modal_title_tips'></span>");
1122
+ $("#machine_instruction_modal_title").html("添加任务<span style='color: #BDBDBD' id='machine_instruction_modal_title_tips'></span>");
1123
1123
  let html = [];
1124
1124
  html.push('<form data-parsley-validate class="form-horizontal form-label-left">');
1125
1125
  html.push('<div class="form-group" id="action_machine_div">');
@@ -1342,7 +1342,7 @@ $(function () {
1342
1342
  if (j.word) {
1343
1343
  $("#word_value").val(j.word);
1344
1344
  $("#word_chinese").val(j.chinese);
1345
- $("#word_modal_title").html(Util.pack_html_link("https://cn.bing.com/dict/search?q=" + j.word, "随机单词") + " <span style='color: #BDBDBD;'>(" + Util.seconds_to_format(j.date) + ")</span>");
1345
+ $("#word_modal_title").html(Util.pack_html_link("https://cn.bing.com/dict/search?q=" + j.word, "随机单词") + " <span style='color: #BDBDBD'>(" + Util.seconds_to_format(j.date) + ")</span>");
1346
1346
  }
1347
1347
  });
1348
1348
  } else {
@@ -1492,11 +1492,11 @@ $(function () {
1492
1492
  $("#base64_action").text($(this).text());
1493
1493
  });
1494
1494
  $("#unicode_convert").click(function () {
1495
- let unicode_str = $("#unicode").val().trim();
1496
- if (unicode_str) {
1495
+ let unicode_string = $("#unicode").val().trim();
1496
+ if (unicode_string) {
1497
1497
  try {
1498
- let obj = JSON.parse('{"data": "' + unicode_str + '"}');
1499
- $("#unicode_result").html("<b class='text-success'>" + obj.data + "</b>");
1498
+ let json_object = JSON.parse('{"data": "' + unicode_string + '"}');
1499
+ $("#unicode_result").html("<b class='text-success'>" + json_object.data + "</b>");
1500
1500
  } catch (error) {
1501
1501
  $("#unicode_result").html("<b class='text-danger'>" + error.message + "</b>");
1502
1502
  }
@@ -1505,11 +1505,11 @@ $(function () {
1505
1505
  }
1506
1506
  });
1507
1507
  $("#segment_parse").click(function () {
1508
- let segment_str = $("#segment").val().trim();
1509
- if (segment_str) {
1508
+ let segment_string = $("#segment").val().trim();
1509
+ if (segment_string) {
1510
1510
  try {
1511
1511
  let segmenter = new Intl.Segmenter("zh-CN", {granularity: "word"});
1512
- let segments = segmenter.segment(segment_str);
1512
+ let segments = segmenter.segment(segment_string);
1513
1513
  let segment_html = [];
1514
1514
  for (let {segment, index, isWordLike} of segments) {
1515
1515
  if (isWordLike) {
package/stock_basics.js CHANGED
@@ -625,62 +625,64 @@ let Stock = {
625
625
 
626
626
  fetch_finance: function () {
627
627
  Util.show_loading();
628
- Util.init_table_skeleton({
629
- "element_id": "cash_flow_table",
630
- "head_columns": [
631
- {"name": "年份"},
632
- {"name": "经营活动现金流"},
633
- {"name": "资本开支"},
634
- {"name": "自由现金流", "tooltip": "自由现金流 = 经营活动现金流 - 资本开支"},
635
- {
636
- "name": "筹资现金净额",
637
- "tooltip": "筹资活动现金流量,是企业现金流量的重要组成部分,其中包含了筹资活动现金流入和筹资活动现金流出两个小部分,筹资活动现金流入减去筹资活动现金流出,就是企业当期筹资活动产生的现金流量净额"
638
- },
639
- ]
640
- });
641
- Util.init_table_skeleton({
642
- "element_id": "assets_liabilities_table",
643
- "head_columns": [
644
- {"name": "年份"},
645
- {"name": "总资产"},
646
- {"name": "总负债"},
647
- {"name": "净资产", "tooltip": "净资产 = 总资产 - 总负债"},
648
- {"name": "资产负债率", "tooltip": "资产负债率 = 总负债 / 总资产", "link": "https://baike.baidu.com/item/资产负债率/2429745"},
649
- {
650
- "name": "货币资金",
651
- "tooltip": "货币资金(Money) 是指企业拥有的,以货币形式存在的资产,包括现金、银行存款和其他货币资金",
652
- "link": "https://baike.baidu.com/item/货币资金/2408229"
653
- },
654
- {"name": "短期借款"},
655
- {"name": "一年非流债", "tooltip": "一年内到期的非流动负债"},
656
- {
657
- "name": "短期还债比",
658
- "tooltip": "货币资金 / (短期借款 + 一年内到期的非流动负债)",
659
- "link": "https://mp.weixin.qq.com/s?__biz=MzAxMjEyOTYwMQ==&mid=2649823683&idx=1&sn=122617d91614ec7b78aa738ca4fdb4ed"
660
- },
661
- {"name": "商誉"},
662
- {"name": "商誉占比"}
663
- ]
664
- });
665
- Util.init_table_skeleton({
666
- "element_id": "profit_table",
667
- "head_columns": [
668
- {"name": "年份-季度"},
669
- {"name": "净利率"},
670
- {"name": "毛利率"},
671
- {"name": "EPS", "tooltip": "每股收益(Earnings Per Share)"},
672
- {"name": "ROE", "tooltip": "净资产收益率(Return On Equity)"},
673
- {"name": "营业收入"},
674
- {"name": "营收同比", "tooltip": "(当前营业收入 - 去年同期的营业收入) / 去年同期的营业收入 × 100%"},
675
- {"name": "营收环比", "tooltip": "(当前营业收入 - 上一季度的营业收入) / 上一季度的营业收入 × 100%"},
676
- {"name": "净利润"},
677
- {"name": "净利同比", "tooltip": "(当前净利润 - 去年同期的净利润) / 去年同期的净利润 × 100%"},
678
- {"name": "净利环比", "tooltip": "(当前净利润 - 上一季度的净利润) / 上一季度的净利润 × 100%"},
679
- {"name": "扣非净利润"},
680
- {"name": "扣净同比", "tooltip": "(当前扣非净利润 - 去年同期的扣非净利润) / 去年同期的扣非净利润 × 100%"},
681
- {"name": "扣净环比", "tooltip": "(当前扣非净利润 - 上一季度的扣非净利润) / 上一季度的扣非净利润 × 100%"},
682
- ]
683
- });
628
+ if (!document.getElementById("cash_flow_table_body")) {
629
+ Util.init_table_skeleton({
630
+ "element_id": "cash_flow_table",
631
+ "head_columns": [
632
+ {"name": "年份"},
633
+ {"name": "经营活动现金流"},
634
+ {"name": "资本开支"},
635
+ {"name": "自由现金流", "tooltip": "自由现金流 = 经营活动现金流 - 资本开支"},
636
+ {
637
+ "name": "筹资现金净额",
638
+ "tooltip": "筹资活动现金流量,是企业现金流量的重要组成部分,其中包含了筹资活动现金流入和筹资活动现金流出两个小部分,筹资活动现金流入减去筹资活动现金流出,就是企业当期筹资活动产生的现金流量净额"
639
+ },
640
+ ]
641
+ });
642
+ Util.init_table_skeleton({
643
+ "element_id": "assets_liabilities_table",
644
+ "head_columns": [
645
+ {"name": "年份"},
646
+ {"name": "总资产"},
647
+ {"name": "总负债"},
648
+ {"name": "净资产", "tooltip": "净资产 = 总资产 - 总负债"},
649
+ {"name": "资产负债率", "tooltip": "资产负债率 = 总负债 / 总资产", "link": "https://baike.baidu.com/item/资产负债率/2429745"},
650
+ {
651
+ "name": "货币资金",
652
+ "tooltip": "货币资金(Money) 是指企业拥有的,以货币形式存在的资产,包括现金、银行存款和其他货币资金",
653
+ "link": "https://baike.baidu.com/item/货币资金/2408229"
654
+ },
655
+ {"name": "短期借款"},
656
+ {"name": "一年非流债", "tooltip": "一年内到期的非流动负债"},
657
+ {
658
+ "name": "短期还债比",
659
+ "tooltip": "货币资金 / (短期借款 + 一年内到期的非流动负债)",
660
+ "link": "https://mp.weixin.qq.com/s?__biz=MzAxMjEyOTYwMQ==&mid=2649823683&idx=1&sn=122617d91614ec7b78aa738ca4fdb4ed"
661
+ },
662
+ {"name": "商誉"},
663
+ {"name": "商誉占比"}
664
+ ]
665
+ });
666
+ Util.init_table_skeleton({
667
+ "element_id": "profit_table",
668
+ "head_columns": [
669
+ {"name": "年份-季度"},
670
+ {"name": "净利率"},
671
+ {"name": "毛利率"},
672
+ {"name": "EPS", "tooltip": "每股收益(Earnings Per Share)"},
673
+ {"name": "ROE", "tooltip": "净资产收益率(Return On Equity)"},
674
+ {"name": "营业收入"},
675
+ {"name": "营收同比", "tooltip": "(当前营业收入 - 去年同期的营业收入) / 去年同期的营业收入 × 100%"},
676
+ {"name": "营收环比", "tooltip": "(当前营业收入 - 上一季度的营业收入) / 上一季度的营业收入 × 100%"},
677
+ {"name": "净利润"},
678
+ {"name": "净利同比", "tooltip": "(当前净利润 - 去年同期的净利润) / 去年同期的净利润 × 100%"},
679
+ {"name": "净利环比", "tooltip": "(当前净利润 - 上一季度的净利润) / 上一季度的净利润 × 100%"},
680
+ {"name": "扣非净利润"},
681
+ {"name": "扣净同比", "tooltip": "(当前扣非净利润 - 去年同期的扣非净利润) / 去年同期的扣非净利润 × 100%"},
682
+ {"name": "扣净环比", "tooltip": "(当前扣非净利润 - 上一季度的扣非净利润) / 上一季度的扣非净利润 × 100%"},
683
+ ]
684
+ });
685
+ }
684
686
  Util.post("/stock/" + Stock.code, {action: "finance"}, function (j) {
685
687
  // 现金流量表
686
688
  let html = [], total_ncf_from_oa = 0, total_cash_paid_for_assets = 0, total_free_cash_flow = 0, total_ncf_from_fa = 0;
@@ -1186,7 +1188,7 @@ let Stock = {
1186
1188
  mm_object.on('shown.bs.modal', function (e) {
1187
1189
  let url = $("#margin_panel_title").find("a").first().attr("href");
1188
1190
  let title = Util.pack_html_link(url, "[" + Stock["name"] + "]融资余额明细数据");
1189
- $("#margin_modal_title").html(title + "<span style='color: #BDBDBD;' id='margin_modal_summary'></span>");
1191
+ $("#margin_modal_title").html(title + "<span style='color: #BDBDBD' id='margin_modal_summary'></span>");
1190
1192
  Util.init_table_skeleton({
1191
1193
  "element_id": "margin_modal_body",
1192
1194
  "caption": "none",
@@ -1306,7 +1308,7 @@ let Stock = {
1306
1308
  hhm_object.on('shown.bs.modal', function (e) {
1307
1309
  let url = $("#hkex_holding_summary").find("a").first().attr("href");
1308
1310
  let title = Util.pack_html_link(url, "[" + Stock["name"] + "]港股通持股明细数据");
1309
- $("#hkex_holding_modal_title").html(title + "<span style='color: #BDBDBD;' id='hkex_holding_modal_summary'></span>");
1311
+ $("#hkex_holding_modal_title").html(title + "<span style='color: #BDBDBD' id='hkex_holding_modal_summary'></span>");
1310
1312
  Util.init_table_skeleton({
1311
1313
  "element_id": "hkex_holding_modal_body",
1312
1314
  "caption": "none",
package/util.js CHANGED
@@ -2913,8 +2913,8 @@ const Util = {
2913
2913
  let origin_txt = tips_object.innerText.replace(/\./g, '');
2914
2914
  if (origin_msg === origin_txt) {
2915
2915
  loading = loading < 5 ? (loading + 1) : 1;
2916
- let load_str = ".".repeat(loading);
2917
- tips_object.innerHTML = origin_msg + load_str;
2916
+ let load_string = ".".repeat(loading);
2917
+ tips_object.innerHTML = origin_msg + load_string;
2918
2918
  setTimeout(() => {
2919
2919
  Util.show_tips(msg, interval, cls, loading);
2920
2920
  }, 300);
@@ -2972,14 +2972,14 @@ const Util = {
2972
2972
  },
2973
2973
 
2974
2974
  tooltip: function (element_id, tip) {
2975
- let obj = $("#" + element_id);
2976
- if (!obj.hasClass("glyphicon")) {
2977
- obj.addClass("glyphicon");
2975
+ let element_object = $("#" + element_id);
2976
+ if (!element_object.hasClass("glyphicon")) {
2977
+ element_object.addClass("glyphicon");
2978
2978
  }
2979
- if (!obj.hasClass("glyphicon-info-sign")) {
2980
- obj.addClass("glyphicon-info-sign");
2979
+ if (!element_object.hasClass("glyphicon-info-sign")) {
2980
+ element_object.addClass("glyphicon-info-sign");
2981
2981
  }
2982
- obj.attr("data-original-title", tip).attr("data-toggle", "tooltip").attr("data-placement", "bottom").attr("data-container", "body").tooltip();
2982
+ element_object.attr("data-original-title", tip).attr("data-toggle", "tooltip").attr("data-placement", "bottom").attr("data-container", "body").tooltip();
2983
2983
  },
2984
2984
 
2985
2985
  /**
@@ -3462,13 +3462,13 @@ const Util = {
3462
3462
  let ma_deduction_html = [];
3463
3463
  item.ma_deduction.forEach(function (ma) {
3464
3464
  if (ma["deduction_price"] > 0) {
3465
- let day_ma_str = ma["day"] + "日均线";
3465
+ let day_ma_string = ma["day"] + "日均线";
3466
3466
  if (ma["day"] === 20 || ma["day"] === 60 || ma["day"] === 120) {
3467
- day_ma_str = "<span class='label label-info'>" + day_ma_str + "</span>";
3467
+ day_ma_string = "<span class='label label-info'>" + day_ma_string + "</span>";
3468
3468
  }
3469
3469
  let deduction_cls = Util.text_color(item.price, ma["deduction_price"]);
3470
3470
  let ma_cls = Util.text_color(item.price, ma["ma"]);
3471
- ma_deduction_html.push(day_ma_str + ":<b class='" + ma_cls + "'>" + ma["ma"] + "</b>(<b class='" + deduction_cls + "'>" + ma["deduction_price"] + "</b>)");
3471
+ ma_deduction_html.push(day_ma_string + ":<b class='" + ma_cls + "'>" + ma["ma"] + "</b>(<b class='" + deduction_cls + "'>" + ma["deduction_price"] + "</b>)");
3472
3472
  }
3473
3473
  });
3474
3474
  $("#" + element_id).html(ma_deduction_html.join("&nbsp;&nbsp;"));