jisilux

在jsl与xueqiu同品种页面间跳转,从xueqiu转到jsl有地址不对的情况,jsl里lof\etf中包含的qdii、封基是分开的,没找到代码上的规律。

目前为 2024-03-03 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name jisilux
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.362
  5. // @description 在jsl与xueqiu同品种页面间跳转,从xueqiu转到jsl有地址不对的情况,jsl里lof\etf中包含的qdii、封基是分开的,没找到代码上的规律。
  6. // @author zhus@live.cn
  7. // @license https://www.apache.org/licenses/LICENSE-2.0
  8. // @include https://*jisilu.cn/data/*
  9. // @include https://*xueqiu.com/*
  10. // @connect 192.168.196.9
  11. // @icon https://www.jisilu.cn/favicon.ico
  12. // @grant GM_xmlhttpRequest
  13. // @run-at document-end
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict'
  18. const xqUrl = 'https://xueqiu.com/S/'
  19. const jslUrl = 'https://www.jisilu.cn/data/'
  20. const sh = /^(11|50|51|56|58|60|68|70|73|90)\d{4}$/ // 沪市证券
  21. const sz = /^(00|08|12|15|16|20|30)\d{4}$/ // 深市证券
  22. const bj = /^(83|87|88)\d{4}$/ //北交所
  23. const cb = /^(110|113|123|127|128)\d{3}$/ // 可转债
  24. const etf = /^(15|51|56|58)\d{4}$/ //这个跳到jsl会有错漏,ETF中的qdii ,jsl是分开的。没有找到分开的规律。
  25. const stock = /^(600|601|603|688|000|002|300)\d{3}$/ //这个不知道有错漏没,没有包括北交所。
  26. const lof = /^(16|50)\d{4}$/ //这个错的最多,qdii 封闭基金 都有可能,没有找到规律。
  27. const server = 'http://192.168.196.9:9096/indicator'
  28.  
  29. //preStart
  30. function purifyCode(code) {
  31. return code.replace(/[a-z]*/gi, '')
  32. }
  33. function addPrefix(code) {
  34. code = purifyCode(code)
  35. if (sh.test(code)) {
  36. return 'SH' + String(code)}
  37. else if (sz.test(code)) {
  38. return 'SZ' + String(code)}
  39. else if (bj.test(code)) {
  40. return 'BJ' + String(code)}
  41. else {
  42. return false
  43. }
  44. }
  45. function classify(code) {
  46. code = purifyCode(code)
  47. if (cb.test(code)) {
  48. return jslUrl.concat('convert_bond_detail/',code)
  49. } else if (etf.test(code)) {
  50. return jslUrl.concat('etf/detail/',code)
  51. } else if (stock.test(code)) {
  52. return jslUrl.concat('stock/detail/',code)
  53. } else if (lof.test(code)) {
  54. return jslUrl.concat('lof/detail/',code)
  55. } else {
  56. return false
  57. }
  58. }
  59.  
  60. function fetchIndicator(code){
  61. let url = server + '?stocks='+ String(code)
  62. var res
  63. GM_xmlhttpRequest({
  64. method: 'GET',
  65. url: url,
  66. onload: function(response) {
  67. let indicator
  68. let hasInfo = $('#app .stock-relation-quote').length
  69. res = JSON.parse(response.response)
  70. let EPS = /\d+\.\d+/.exec($('#app .quote-info')[0].innerHTML.match(/每股收益\D+\d+\.\d+/)[0])[0]
  71. let BVPS = /\d+\.\d+/.exec($('#app .quote-info')[0].innerHTML.match(/每股净资产\D+\d+\.\d+/)[0])[0]
  72. let roe = (parseFloat(EPS)/parseFloat(BVPS)*100).toFixed(1)
  73. if (res) {
  74. let alr = res.alr.toFixed(1)
  75. let alrColor = alr > 50 ? '#dd2200':'#093'
  76. indicator = `&emsp;<span>Roe </span><span style='color:#07d'>${roe}% </span><span >负债 </span><span style='color:${alrColor}'>${alr}% </span>`
  77. } else {
  78. indicator = `&emsp;<span>Roe </span><span style='color:#07d'>${roe}% </span>`
  79. }
  80. if (hasInfo == 0) {
  81. $('#app .stock-info').eq(0).after(`<a class="stock-relation" >Extra Indicators${indicator}</a>`)
  82. } else {
  83. $('#app .stock-relation-quote').eq(0).after(indicator)
  84. }
  85. if (code.match('S[HZ]')&&stock.test(purifyCode(code))){
  86. new MutationObserver((recordList) => {
  87. if (hasInfo == 0) {
  88. $('#app .stock-info').eq(0).after(`<a class="stock-relation" >Extra Indicators${indicator}</a>`)
  89. } else {
  90. $('#app .stock-relation-quote').eq(0).after(indicator)
  91. }
  92. }).observe( document.querySelector( 'div.quote-container' ), {
  93. childList: true
  94. })
  95. }
  96. },
  97. onerror: function(error) {
  98. console.error("Request failed:", error)
  99. }
  100. })
  101. }
  102. // start
  103. window.addEventListener('load', function() {
  104. let code = location.pathname.split('/').pop()
  105. if (location.hostname.replace('www.', '') === 'jisilu.cn') {
  106. let fullCode = addPrefix(code)
  107. if (!fullCode) { return }
  108. let xqUrlDetail = xqUrl.concat(fullCode)
  109. let xq = `<div style="flex:1 1 auto;"><a href= ${xqUrlDetail} target='_blank'> <img src='https://xueqiu.com/favicon.ico' width="20px" /></a></div>`
  110. let xq2 = `<li><a href= ${xqUrlDetail} target='_blank'> <img src='https://xueqiu.com/favicon.ico' width="18px" /></a></li>`
  111. if ( $('#compare_top').length > 0 ) {
  112. $('#compare_top > .left_title').after(xq)
  113. }
  114. if ( $('ol.breadcrumb').length > 0) {
  115. $('ol.breadcrumb > li.active').after(xq2)
  116. }
  117. }
  118. //
  119. if (location.hostname.replace('www.', '') === 'xueqiu.com') {
  120. if (location.pathname.match(/^\/[0-9]{10}\/[0-9]{8}/)) {
  121. [...document.querySelectorAll('div.article__container')].forEach(item=>{
  122. item.oncopy = function(e) {
  123. e.stopPropagation()
  124. }
  125. })
  126. $('.article__bd__detail h-char').removeClass('bd-hangable')
  127. } else if (location.pathname.match(/^\/S\//)) {
  128. fetchIndicator(code)
  129. let jslUrlDtail = classify(code)
  130. if (!jslUrlDtail) { return }
  131. let jsl = `&emsp; <a href= ${jslUrlDtail} target='_blank'><img style='height: 1.5rem' src='https://www.jisilu.cn/favicon.ico' /></a>`
  132. $('#app .stock-name').eq(0).after(jsl)
  133. }
  134. }
  135. })
  136. })()